Call fatal_insn_not_found instead of abort
[official-gcc.git] / gcc / optabs.c
blob4b31fe0d106433960ea3f0e098e20e7d40218026
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "insn-flags.h"
28 #include "insn-codes.h"
29 #include "expr.h"
30 #include "insn-config.h"
31 #include "recog.h"
32 #include "reload.h"
34 /* Each optab contains info on how this target machine
35 can perform a particular operation
36 for all sizes and kinds of operands.
38 The operation to be performed is often specified
39 by passing one of these optabs as an argument.
41 See expr.h for documentation of these optabs. */
43 optab add_optab;
44 optab sub_optab;
45 optab smul_optab;
46 optab smul_highpart_optab;
47 optab umul_highpart_optab;
48 optab smul_widen_optab;
49 optab umul_widen_optab;
50 optab sdiv_optab;
51 optab sdivmod_optab;
52 optab udiv_optab;
53 optab udivmod_optab;
54 optab smod_optab;
55 optab umod_optab;
56 optab flodiv_optab;
57 optab ftrunc_optab;
58 optab and_optab;
59 optab ior_optab;
60 optab xor_optab;
61 optab ashl_optab;
62 optab lshr_optab;
63 optab ashr_optab;
64 optab rotl_optab;
65 optab rotr_optab;
66 optab smin_optab;
67 optab smax_optab;
68 optab umin_optab;
69 optab umax_optab;
71 optab mov_optab;
72 optab movstrict_optab;
74 optab neg_optab;
75 optab abs_optab;
76 optab one_cmpl_optab;
77 optab ffs_optab;
78 optab sqrt_optab;
79 optab sin_optab;
80 optab cos_optab;
82 optab cmp_optab;
83 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
84 optab tst_optab;
86 optab strlen_optab;
88 /* Tables of patterns for extending one integer mode to another. */
89 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
91 /* Tables of patterns for converting between fixed and floating point. */
92 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
96 /* Contains the optab used for each rtx code. */
97 optab code_to_optab[NUM_RTX_CODE + 1];
99 /* SYMBOL_REF rtx's for the library functions that are called
100 implicitly and not via optabs. */
102 rtx extendsfdf2_libfunc;
103 rtx extendsfxf2_libfunc;
104 rtx extendsftf2_libfunc;
105 rtx extenddfxf2_libfunc;
106 rtx extenddftf2_libfunc;
108 rtx truncdfsf2_libfunc;
109 rtx truncxfsf2_libfunc;
110 rtx trunctfsf2_libfunc;
111 rtx truncxfdf2_libfunc;
112 rtx trunctfdf2_libfunc;
114 rtx memcpy_libfunc;
115 rtx bcopy_libfunc;
116 rtx memcmp_libfunc;
117 rtx bcmp_libfunc;
118 rtx memset_libfunc;
119 rtx bzero_libfunc;
121 rtx throw_libfunc;
122 rtx sjthrow_libfunc;
123 rtx sjpopnthrow_libfunc;
124 rtx terminate_libfunc;
125 rtx setjmp_libfunc;
126 rtx longjmp_libfunc;
128 rtx eqhf2_libfunc;
129 rtx nehf2_libfunc;
130 rtx gthf2_libfunc;
131 rtx gehf2_libfunc;
132 rtx lthf2_libfunc;
133 rtx lehf2_libfunc;
135 rtx eqsf2_libfunc;
136 rtx nesf2_libfunc;
137 rtx gtsf2_libfunc;
138 rtx gesf2_libfunc;
139 rtx ltsf2_libfunc;
140 rtx lesf2_libfunc;
142 rtx eqdf2_libfunc;
143 rtx nedf2_libfunc;
144 rtx gtdf2_libfunc;
145 rtx gedf2_libfunc;
146 rtx ltdf2_libfunc;
147 rtx ledf2_libfunc;
149 rtx eqxf2_libfunc;
150 rtx nexf2_libfunc;
151 rtx gtxf2_libfunc;
152 rtx gexf2_libfunc;
153 rtx ltxf2_libfunc;
154 rtx lexf2_libfunc;
156 rtx eqtf2_libfunc;
157 rtx netf2_libfunc;
158 rtx gttf2_libfunc;
159 rtx getf2_libfunc;
160 rtx lttf2_libfunc;
161 rtx letf2_libfunc;
163 rtx floatsisf_libfunc;
164 rtx floatdisf_libfunc;
165 rtx floattisf_libfunc;
167 rtx floatsidf_libfunc;
168 rtx floatdidf_libfunc;
169 rtx floattidf_libfunc;
171 rtx floatsixf_libfunc;
172 rtx floatdixf_libfunc;
173 rtx floattixf_libfunc;
175 rtx floatsitf_libfunc;
176 rtx floatditf_libfunc;
177 rtx floattitf_libfunc;
179 rtx fixsfsi_libfunc;
180 rtx fixsfdi_libfunc;
181 rtx fixsfti_libfunc;
183 rtx fixdfsi_libfunc;
184 rtx fixdfdi_libfunc;
185 rtx fixdfti_libfunc;
187 rtx fixxfsi_libfunc;
188 rtx fixxfdi_libfunc;
189 rtx fixxfti_libfunc;
191 rtx fixtfsi_libfunc;
192 rtx fixtfdi_libfunc;
193 rtx fixtfti_libfunc;
195 rtx fixunssfsi_libfunc;
196 rtx fixunssfdi_libfunc;
197 rtx fixunssfti_libfunc;
199 rtx fixunsdfsi_libfunc;
200 rtx fixunsdfdi_libfunc;
201 rtx fixunsdfti_libfunc;
203 rtx fixunsxfsi_libfunc;
204 rtx fixunsxfdi_libfunc;
205 rtx fixunsxfti_libfunc;
207 rtx fixunstfsi_libfunc;
208 rtx fixunstfdi_libfunc;
209 rtx fixunstfti_libfunc;
211 rtx chkr_check_addr_libfunc;
212 rtx chkr_set_right_libfunc;
213 rtx chkr_copy_bitmap_libfunc;
214 rtx chkr_check_exec_libfunc;
215 rtx chkr_check_str_libfunc;
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the gen_function to make a branch to test that condition. */
220 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
222 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
223 gives the insn code to make a store-condition insn
224 to test that condition. */
226 enum insn_code setcc_gen_code[NUM_RTX_CODE];
228 #ifdef HAVE_conditional_move
229 /* Indexed by the machine mode, gives the insn code to make a conditional
230 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
231 setcc_gen_code to cut down on the number of named patterns. Consider a day
232 when a lot more rtx codes are conditional (eg: for the ARM). */
234 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
235 #endif
237 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
238 static rtx widen_operand PROTO((rtx, enum machine_mode,
239 enum machine_mode, int, int));
240 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
241 int, int *));
242 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
243 int));
244 static rtx ftruncify PROTO((rtx));
245 static optab init_optab PROTO((enum rtx_code));
246 static void init_libfuncs PROTO((optab, int, int, char *, int));
247 static void init_integral_libfuncs PROTO((optab, char *, int));
248 static void init_floating_libfuncs PROTO((optab, char *, int));
249 #ifdef HAVE_conditional_trap
250 static void init_traps PROTO((void));
251 #endif
253 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
254 the result of operation CODE applied to OP0 (and OP1 if it is a binary
255 operation).
257 If the last insn does not set TARGET, don't do anything, but return 1.
259 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
260 don't add the REG_EQUAL note but return 0. Our caller can then try
261 again, ensuring that TARGET is not one of the operands. */
263 static int
264 add_equal_note (seq, target, code, op0, op1)
265 rtx seq;
266 rtx target;
267 enum rtx_code code;
268 rtx op0, op1;
270 rtx set;
271 int i;
272 rtx note;
274 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
275 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
276 || GET_CODE (seq) != SEQUENCE
277 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
278 || GET_CODE (target) == ZERO_EXTRACT
279 || (! rtx_equal_p (SET_DEST (set), target)
280 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
281 SUBREG. */
282 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
283 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
284 target))))
285 return 1;
287 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
288 besides the last insn. */
289 if (reg_overlap_mentioned_p (target, op0)
290 || (op1 && reg_overlap_mentioned_p (target, op1)))
291 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
292 if (reg_set_p (target, XVECEXP (seq, 0, i)))
293 return 0;
295 if (GET_RTX_CLASS (code) == '1')
296 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
297 else
298 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
300 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
301 = gen_rtx_EXPR_LIST (REG_EQUAL, note,
302 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
304 return 1;
307 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
308 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
309 not actually do a sign-extend or zero-extend, but can leave the
310 higher-order bits of the result rtx undefined, for example, in the case
311 of logical operations, but not right shifts. */
313 static rtx
314 widen_operand (op, mode, oldmode, unsignedp, no_extend)
315 rtx op;
316 enum machine_mode mode, oldmode;
317 int unsignedp;
318 int no_extend;
320 rtx result;
322 /* If we must extend do so. If OP is either a constant or a SUBREG
323 for a promoted object, also extend since it will be more efficient to
324 do so. */
325 if (! no_extend
326 || GET_MODE (op) == VOIDmode
327 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
328 return convert_modes (mode, oldmode, op, unsignedp);
330 /* If MODE is no wider than a single word, we return a paradoxical
331 SUBREG. */
332 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
333 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
335 /* Otherwise, get an object of MODE, clobber it, and set the low-order
336 part to OP. */
338 result = gen_reg_rtx (mode);
339 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
340 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
341 return result;
344 /* Generate code to perform an operation specified by BINOPTAB
345 on operands OP0 and OP1, with result having machine-mode MODE.
347 UNSIGNEDP is for the case where we have to widen the operands
348 to perform the operation. It says to use zero-extension.
350 If TARGET is nonzero, the value
351 is generated there, if it is convenient to do so.
352 In all cases an rtx is returned for the locus of the value;
353 this may or may not be TARGET. */
356 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
357 enum machine_mode mode;
358 optab binoptab;
359 rtx op0, op1;
360 rtx target;
361 int unsignedp;
362 enum optab_methods methods;
364 enum optab_methods next_methods
365 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
366 ? OPTAB_WIDEN : methods);
367 enum mode_class class;
368 enum machine_mode wider_mode;
369 register rtx temp;
370 int commutative_op = 0;
371 int shift_op = (binoptab->code == ASHIFT
372 || binoptab->code == ASHIFTRT
373 || binoptab->code == LSHIFTRT
374 || binoptab->code == ROTATE
375 || binoptab->code == ROTATERT);
376 rtx entry_last = get_last_insn ();
377 rtx last;
379 class = GET_MODE_CLASS (mode);
381 op0 = protect_from_queue (op0, 0);
382 op1 = protect_from_queue (op1, 0);
383 if (target)
384 target = protect_from_queue (target, 1);
386 if (flag_force_mem)
388 op0 = force_not_mem (op0);
389 op1 = force_not_mem (op1);
392 /* If subtracting an integer constant, convert this into an addition of
393 the negated constant. */
395 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
397 op1 = negate_rtx (mode, op1);
398 binoptab = add_optab;
401 /* If we are inside an appropriately-short loop and one operand is an
402 expensive constant, force it into a register. */
403 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
404 && rtx_cost (op0, binoptab->code) > 2)
405 op0 = force_reg (mode, op0);
407 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
408 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
409 op1 = force_reg (mode, op1);
411 /* Record where to delete back to if we backtrack. */
412 last = get_last_insn ();
414 /* If operation is commutative,
415 try to make the first operand a register.
416 Even better, try to make it the same as the target.
417 Also try to make the last operand a constant. */
418 if (GET_RTX_CLASS (binoptab->code) == 'c'
419 || binoptab == smul_widen_optab
420 || binoptab == umul_widen_optab
421 || binoptab == smul_highpart_optab
422 || binoptab == umul_highpart_optab)
424 commutative_op = 1;
426 if (((target == 0 || GET_CODE (target) == REG)
427 ? ((GET_CODE (op1) == REG
428 && GET_CODE (op0) != REG)
429 || target == op1)
430 : rtx_equal_p (op1, target))
431 || GET_CODE (op0) == CONST_INT)
433 temp = op1;
434 op1 = op0;
435 op0 = temp;
439 /* If we can do it with a three-operand insn, do so. */
441 if (methods != OPTAB_MUST_WIDEN
442 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
444 int icode = (int) binoptab->handlers[(int) mode].insn_code;
445 enum machine_mode mode0 = insn_operand_mode[icode][1];
446 enum machine_mode mode1 = insn_operand_mode[icode][2];
447 rtx pat;
448 rtx xop0 = op0, xop1 = op1;
450 if (target)
451 temp = target;
452 else
453 temp = gen_reg_rtx (mode);
455 /* If it is a commutative operator and the modes would match
456 if we would swap the operands, we can save the conversions. */
457 if (commutative_op)
459 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
460 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
462 register rtx tmp;
464 tmp = op0; op0 = op1; op1 = tmp;
465 tmp = xop0; xop0 = xop1; xop1 = tmp;
469 /* In case the insn wants input operands in modes different from
470 the result, convert the operands. */
472 if (GET_MODE (op0) != VOIDmode
473 && GET_MODE (op0) != mode0
474 && mode0 != VOIDmode)
475 xop0 = convert_to_mode (mode0, xop0, unsignedp);
477 if (GET_MODE (xop1) != VOIDmode
478 && GET_MODE (xop1) != mode1
479 && mode1 != VOIDmode)
480 xop1 = convert_to_mode (mode1, xop1, unsignedp);
482 /* Now, if insn's predicates don't allow our operands, put them into
483 pseudo regs. */
485 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
486 && mode0 != VOIDmode)
487 xop0 = copy_to_mode_reg (mode0, xop0);
489 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
490 && mode1 != VOIDmode)
491 xop1 = copy_to_mode_reg (mode1, xop1);
493 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
494 temp = gen_reg_rtx (mode);
496 pat = GEN_FCN (icode) (temp, xop0, xop1);
497 if (pat)
499 /* If PAT is a multi-insn sequence, try to add an appropriate
500 REG_EQUAL note to it. If we can't because TEMP conflicts with an
501 operand, call ourselves again, this time without a target. */
502 if (GET_CODE (pat) == SEQUENCE
503 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
505 delete_insns_since (last);
506 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
507 unsignedp, methods);
510 emit_insn (pat);
511 return temp;
513 else
514 delete_insns_since (last);
517 /* If this is a multiply, see if we can do a widening operation that
518 takes operands of this mode and makes a wider mode. */
520 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
521 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
522 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
523 != CODE_FOR_nothing))
525 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
526 unsignedp ? umul_widen_optab : smul_widen_optab,
527 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
529 if (temp != 0)
531 if (GET_MODE_CLASS (mode) == MODE_INT)
532 return gen_lowpart (mode, temp);
533 else
534 return convert_to_mode (mode, temp, unsignedp);
538 /* Look for a wider mode of the same class for which we think we
539 can open-code the operation. Check for a widening multiply at the
540 wider mode as well. */
542 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
543 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
544 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
545 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
547 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
548 || (binoptab == smul_optab
549 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
550 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
551 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
552 != CODE_FOR_nothing)))
554 rtx xop0 = op0, xop1 = op1;
555 int no_extend = 0;
557 /* For certain integer operations, we need not actually extend
558 the narrow operands, as long as we will truncate
559 the results to the same narrowness. */
561 if ((binoptab == ior_optab || binoptab == and_optab
562 || binoptab == xor_optab
563 || binoptab == add_optab || binoptab == sub_optab
564 || binoptab == smul_optab || binoptab == ashl_optab)
565 && class == MODE_INT)
566 no_extend = 1;
568 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
570 /* The second operand of a shift must always be extended. */
571 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
572 no_extend && binoptab != ashl_optab);
574 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
575 unsignedp, OPTAB_DIRECT);
576 if (temp)
578 if (class != MODE_INT)
580 if (target == 0)
581 target = gen_reg_rtx (mode);
582 convert_move (target, temp, 0);
583 return target;
585 else
586 return gen_lowpart (mode, temp);
588 else
589 delete_insns_since (last);
593 /* These can be done a word at a time. */
594 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
595 && class == MODE_INT
596 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
597 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
599 int i;
600 rtx insns;
601 rtx equiv_value;
603 /* If TARGET is the same as one of the operands, the REG_EQUAL note
604 won't be accurate, so use a new target. */
605 if (target == 0 || target == op0 || target == op1)
606 target = gen_reg_rtx (mode);
608 start_sequence ();
610 /* Do the actual arithmetic. */
611 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
613 rtx target_piece = operand_subword (target, i, 1, mode);
614 rtx x = expand_binop (word_mode, binoptab,
615 operand_subword_force (op0, i, mode),
616 operand_subword_force (op1, i, mode),
617 target_piece, unsignedp, next_methods);
619 if (x == 0)
620 break;
622 if (target_piece != x)
623 emit_move_insn (target_piece, x);
626 insns = get_insns ();
627 end_sequence ();
629 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
631 if (binoptab->code != UNKNOWN)
632 equiv_value
633 = gen_rtx_fmt_ee (binoptab->code, mode,
634 copy_rtx (op0), copy_rtx (op1));
635 else
636 equiv_value = 0;
638 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
639 return target;
643 /* Synthesize double word shifts from single word shifts. */
644 if ((binoptab == lshr_optab || binoptab == ashl_optab
645 || binoptab == ashr_optab)
646 && class == MODE_INT
647 && GET_CODE (op1) == CONST_INT
648 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
649 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
650 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
651 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
653 rtx insns, inter, equiv_value;
654 rtx into_target, outof_target;
655 rtx into_input, outof_input;
656 int shift_count, left_shift, outof_word;
658 /* If TARGET is the same as one of the operands, the REG_EQUAL note
659 won't be accurate, so use a new target. */
660 if (target == 0 || target == op0 || target == op1)
661 target = gen_reg_rtx (mode);
663 start_sequence ();
665 shift_count = INTVAL (op1);
667 /* OUTOF_* is the word we are shifting bits away from, and
668 INTO_* is the word that we are shifting bits towards, thus
669 they differ depending on the direction of the shift and
670 WORDS_BIG_ENDIAN. */
672 left_shift = binoptab == ashl_optab;
673 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
675 outof_target = operand_subword (target, outof_word, 1, mode);
676 into_target = operand_subword (target, 1 - outof_word, 1, mode);
678 outof_input = operand_subword_force (op0, outof_word, mode);
679 into_input = operand_subword_force (op0, 1 - outof_word, mode);
681 if (shift_count >= BITS_PER_WORD)
683 inter = expand_binop (word_mode, binoptab,
684 outof_input,
685 GEN_INT (shift_count - BITS_PER_WORD),
686 into_target, unsignedp, next_methods);
688 if (inter != 0 && inter != into_target)
689 emit_move_insn (into_target, inter);
691 /* For a signed right shift, we must fill the word we are shifting
692 out of with copies of the sign bit. Otherwise it is zeroed. */
693 if (inter != 0 && binoptab != ashr_optab)
694 inter = CONST0_RTX (word_mode);
695 else if (inter != 0)
696 inter = expand_binop (word_mode, binoptab,
697 outof_input,
698 GEN_INT (BITS_PER_WORD - 1),
699 outof_target, unsignedp, next_methods);
701 if (inter != 0 && inter != outof_target)
702 emit_move_insn (outof_target, inter);
704 else
706 rtx carries;
707 optab reverse_unsigned_shift, unsigned_shift;
709 /* For a shift of less then BITS_PER_WORD, to compute the carry,
710 we must do a logical shift in the opposite direction of the
711 desired shift. */
713 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
715 /* For a shift of less than BITS_PER_WORD, to compute the word
716 shifted towards, we need to unsigned shift the orig value of
717 that word. */
719 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
721 carries = expand_binop (word_mode, reverse_unsigned_shift,
722 outof_input,
723 GEN_INT (BITS_PER_WORD - shift_count),
724 0, unsignedp, next_methods);
726 if (carries == 0)
727 inter = 0;
728 else
729 inter = expand_binop (word_mode, unsigned_shift, into_input,
730 op1, 0, unsignedp, next_methods);
732 if (inter != 0)
733 inter = expand_binop (word_mode, ior_optab, carries, inter,
734 into_target, unsignedp, next_methods);
736 if (inter != 0 && inter != into_target)
737 emit_move_insn (into_target, inter);
739 if (inter != 0)
740 inter = expand_binop (word_mode, binoptab, outof_input,
741 op1, outof_target, unsignedp, next_methods);
743 if (inter != 0 && inter != outof_target)
744 emit_move_insn (outof_target, inter);
747 insns = get_insns ();
748 end_sequence ();
750 if (inter != 0)
752 if (binoptab->code != UNKNOWN)
753 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
754 else
755 equiv_value = 0;
757 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
758 return target;
762 /* Synthesize double word rotates from single word shifts. */
763 if ((binoptab == rotl_optab || binoptab == rotr_optab)
764 && class == MODE_INT
765 && GET_CODE (op1) == CONST_INT
766 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
767 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
768 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
770 rtx insns, equiv_value;
771 rtx into_target, outof_target;
772 rtx into_input, outof_input;
773 rtx inter;
774 int shift_count, left_shift, outof_word;
776 /* If TARGET is the same as one of the operands, the REG_EQUAL note
777 won't be accurate, so use a new target. */
778 if (target == 0 || target == op0 || target == op1)
779 target = gen_reg_rtx (mode);
781 start_sequence ();
783 shift_count = INTVAL (op1);
785 /* OUTOF_* is the word we are shifting bits away from, and
786 INTO_* is the word that we are shifting bits towards, thus
787 they differ depending on the direction of the shift and
788 WORDS_BIG_ENDIAN. */
790 left_shift = (binoptab == rotl_optab);
791 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
793 outof_target = operand_subword (target, outof_word, 1, mode);
794 into_target = operand_subword (target, 1 - outof_word, 1, mode);
796 outof_input = operand_subword_force (op0, outof_word, mode);
797 into_input = operand_subword_force (op0, 1 - outof_word, mode);
799 if (shift_count == BITS_PER_WORD)
801 /* This is just a word swap. */
802 emit_move_insn (outof_target, into_input);
803 emit_move_insn (into_target, outof_input);
804 inter = const0_rtx;
806 else
808 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
809 rtx first_shift_count, second_shift_count;
810 optab reverse_unsigned_shift, unsigned_shift;
812 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
813 ? lshr_optab : ashl_optab);
815 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
816 ? ashl_optab : lshr_optab);
818 if (shift_count > BITS_PER_WORD)
820 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
821 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
823 else
825 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
826 second_shift_count = GEN_INT (shift_count);
829 into_temp1 = expand_binop (word_mode, unsigned_shift,
830 outof_input, first_shift_count,
831 NULL_RTX, unsignedp, next_methods);
832 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
833 into_input, second_shift_count,
834 into_target, unsignedp, next_methods);
836 if (into_temp1 != 0 && into_temp2 != 0)
837 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
838 into_target, unsignedp, next_methods);
839 else
840 inter = 0;
842 if (inter != 0 && inter != into_target)
843 emit_move_insn (into_target, inter);
845 outof_temp1 = expand_binop (word_mode, unsigned_shift,
846 into_input, first_shift_count,
847 NULL_RTX, unsignedp, next_methods);
848 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
849 outof_input, second_shift_count,
850 outof_target, unsignedp, next_methods);
852 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
853 inter = expand_binop (word_mode, ior_optab,
854 outof_temp1, outof_temp2,
855 outof_target, unsignedp, next_methods);
857 if (inter != 0 && inter != outof_target)
858 emit_move_insn (outof_target, inter);
861 insns = get_insns ();
862 end_sequence ();
864 if (inter != 0)
866 if (binoptab->code != UNKNOWN)
867 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
868 else
869 equiv_value = 0;
871 /* We can't make this a no conflict block if this is a word swap,
872 because the word swap case fails if the input and output values
873 are in the same register. */
874 if (shift_count != BITS_PER_WORD)
875 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
876 else
877 emit_insns (insns);
880 return target;
884 /* These can be done a word at a time by propagating carries. */
885 if ((binoptab == add_optab || binoptab == sub_optab)
886 && class == MODE_INT
887 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
888 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
890 int i;
891 rtx carry_tmp = gen_reg_rtx (word_mode);
892 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
893 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
894 rtx carry_in, carry_out;
895 rtx xop0, xop1;
897 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
898 value is one of those, use it. Otherwise, use 1 since it is the
899 one easiest to get. */
900 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
901 int normalizep = STORE_FLAG_VALUE;
902 #else
903 int normalizep = 1;
904 #endif
906 /* Prepare the operands. */
907 xop0 = force_reg (mode, op0);
908 xop1 = force_reg (mode, op1);
910 if (target == 0 || GET_CODE (target) != REG
911 || target == xop0 || target == xop1)
912 target = gen_reg_rtx (mode);
914 /* Indicate for flow that the entire target reg is being set. */
915 if (GET_CODE (target) == REG)
916 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
918 /* Do the actual arithmetic. */
919 for (i = 0; i < nwords; i++)
921 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
922 rtx target_piece = operand_subword (target, index, 1, mode);
923 rtx op0_piece = operand_subword_force (xop0, index, mode);
924 rtx op1_piece = operand_subword_force (xop1, index, mode);
925 rtx x;
927 /* Main add/subtract of the input operands. */
928 x = expand_binop (word_mode, binoptab,
929 op0_piece, op1_piece,
930 target_piece, unsignedp, next_methods);
931 if (x == 0)
932 break;
934 if (i + 1 < nwords)
936 /* Store carry from main add/subtract. */
937 carry_out = gen_reg_rtx (word_mode);
938 carry_out = emit_store_flag_force (carry_out,
939 (binoptab == add_optab
940 ? LTU : GTU),
941 x, op0_piece,
942 word_mode, 1, normalizep);
945 if (i > 0)
947 /* Add/subtract previous carry to main result. */
948 x = expand_binop (word_mode,
949 normalizep == 1 ? binoptab : otheroptab,
950 x, carry_in,
951 target_piece, 1, next_methods);
952 if (x == 0)
953 break;
954 else if (target_piece != x)
955 emit_move_insn (target_piece, x);
957 if (i + 1 < nwords)
959 /* THIS CODE HAS NOT BEEN TESTED. */
960 /* Get out carry from adding/subtracting carry in. */
961 carry_tmp = emit_store_flag_force (carry_tmp,
962 binoptab == add_optab
963 ? LTU : GTU,
964 x, carry_in,
965 word_mode, 1, normalizep);
967 /* Logical-ior the two poss. carry together. */
968 carry_out = expand_binop (word_mode, ior_optab,
969 carry_out, carry_tmp,
970 carry_out, 0, next_methods);
971 if (carry_out == 0)
972 break;
976 carry_in = carry_out;
979 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
981 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
983 rtx temp = emit_move_insn (target, target);
985 REG_NOTES (temp)
986 = gen_rtx_EXPR_LIST (REG_EQUAL,
987 gen_rtx_fmt_ee (binoptab->code, mode,
988 copy_rtx (xop0),
989 copy_rtx (xop1)),
990 REG_NOTES (temp));
992 return target;
994 else
995 delete_insns_since (last);
998 /* If we want to multiply two two-word values and have normal and widening
999 multiplies of single-word values, we can do this with three smaller
1000 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1001 because we are not operating on one word at a time.
1003 The multiplication proceeds as follows:
1004 _______________________
1005 [__op0_high_|__op0_low__]
1006 _______________________
1007 * [__op1_high_|__op1_low__]
1008 _______________________________________________
1009 _______________________
1010 (1) [__op0_low__*__op1_low__]
1011 _______________________
1012 (2a) [__op0_low__*__op1_high_]
1013 _______________________
1014 (2b) [__op0_high_*__op1_low__]
1015 _______________________
1016 (3) [__op0_high_*__op1_high_]
1019 This gives a 4-word result. Since we are only interested in the
1020 lower 2 words, partial result (3) and the upper words of (2a) and
1021 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1022 calculated using non-widening multiplication.
1024 (1), however, needs to be calculated with an unsigned widening
1025 multiplication. If this operation is not directly supported we
1026 try using a signed widening multiplication and adjust the result.
1027 This adjustment works as follows:
1029 If both operands are positive then no adjustment is needed.
1031 If the operands have different signs, for example op0_low < 0 and
1032 op1_low >= 0, the instruction treats the most significant bit of
1033 op0_low as a sign bit instead of a bit with significance
1034 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1035 with 2**BITS_PER_WORD - op0_low, and two's complements the
1036 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1037 the result.
1039 Similarly, if both operands are negative, we need to add
1040 (op0_low + op1_low) * 2**BITS_PER_WORD.
1042 We use a trick to adjust quickly. We logically shift op0_low right
1043 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1044 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1045 logical shift exists, we do an arithmetic right shift and subtract
1046 the 0 or -1. */
1048 if (binoptab == smul_optab
1049 && class == MODE_INT
1050 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1051 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1052 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1053 && ((umul_widen_optab->handlers[(int) mode].insn_code
1054 != CODE_FOR_nothing)
1055 || (smul_widen_optab->handlers[(int) mode].insn_code
1056 != CODE_FOR_nothing)))
1058 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1059 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1060 rtx op0_high = operand_subword_force (op0, high, mode);
1061 rtx op0_low = operand_subword_force (op0, low, mode);
1062 rtx op1_high = operand_subword_force (op1, high, mode);
1063 rtx op1_low = operand_subword_force (op1, low, mode);
1064 rtx product = 0;
1065 rtx op0_xhigh;
1066 rtx op1_xhigh;
1068 /* If the target is the same as one of the inputs, don't use it. This
1069 prevents problems with the REG_EQUAL note. */
1070 if (target == op0 || target == op1
1071 || (target != 0 && GET_CODE (target) != REG))
1072 target = 0;
1074 /* Multiply the two lower words to get a double-word product.
1075 If unsigned widening multiplication is available, use that;
1076 otherwise use the signed form and compensate. */
1078 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1080 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1081 target, 1, OPTAB_DIRECT);
1083 /* If we didn't succeed, delete everything we did so far. */
1084 if (product == 0)
1085 delete_insns_since (last);
1086 else
1087 op0_xhigh = op0_high, op1_xhigh = op1_high;
1090 if (product == 0
1091 && smul_widen_optab->handlers[(int) mode].insn_code
1092 != CODE_FOR_nothing)
1094 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1095 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1096 target, 1, OPTAB_DIRECT);
1097 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1098 NULL_RTX, 1, next_methods);
1099 if (op0_xhigh)
1100 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1101 op0_xhigh, op0_xhigh, 0, next_methods);
1102 else
1104 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1105 NULL_RTX, 0, next_methods);
1106 if (op0_xhigh)
1107 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1108 op0_xhigh, op0_xhigh, 0,
1109 next_methods);
1112 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1113 NULL_RTX, 1, next_methods);
1114 if (op1_xhigh)
1115 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1116 op1_xhigh, op1_xhigh, 0, next_methods);
1117 else
1119 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1120 NULL_RTX, 0, next_methods);
1121 if (op1_xhigh)
1122 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1123 op1_xhigh, op1_xhigh, 0,
1124 next_methods);
1128 /* If we have been able to directly compute the product of the
1129 low-order words of the operands and perform any required adjustments
1130 of the operands, we proceed by trying two more multiplications
1131 and then computing the appropriate sum.
1133 We have checked above that the required addition is provided.
1134 Full-word addition will normally always succeed, especially if
1135 it is provided at all, so we don't worry about its failure. The
1136 multiplication may well fail, however, so we do handle that. */
1138 if (product && op0_xhigh && op1_xhigh)
1140 rtx product_high = operand_subword (product, high, 1, mode);
1141 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1142 NULL_RTX, 0, OPTAB_DIRECT);
1144 if (temp != 0)
1145 temp = expand_binop (word_mode, add_optab, temp, product_high,
1146 product_high, 0, next_methods);
1148 if (temp != 0 && temp != product_high)
1149 emit_move_insn (product_high, temp);
1151 if (temp != 0)
1152 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1153 NULL_RTX, 0, OPTAB_DIRECT);
1155 if (temp != 0)
1156 temp = expand_binop (word_mode, add_optab, temp,
1157 product_high, product_high,
1158 0, next_methods);
1160 if (temp != 0 && temp != product_high)
1161 emit_move_insn (product_high, temp);
1163 if (temp != 0)
1165 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1167 temp = emit_move_insn (product, product);
1168 REG_NOTES (temp)
1169 = gen_rtx_EXPR_LIST (REG_EQUAL,
1170 gen_rtx_fmt_ee (MULT, mode,
1171 copy_rtx (op0),
1172 copy_rtx (op1)),
1173 REG_NOTES (temp));
1175 return product;
1179 /* If we get here, we couldn't do it for some reason even though we
1180 originally thought we could. Delete anything we've emitted in
1181 trying to do it. */
1183 delete_insns_since (last);
1186 /* We need to open-code the complex type operations: '+, -, * and /' */
1188 /* At this point we allow operations between two similar complex
1189 numbers, and also if one of the operands is not a complex number
1190 but rather of MODE_FLOAT or MODE_INT. However, the caller
1191 must make sure that the MODE of the non-complex operand matches
1192 the SUBMODE of the complex operand. */
1194 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1196 rtx real0 = 0, imag0 = 0;
1197 rtx real1 = 0, imag1 = 0;
1198 rtx realr, imagr, res;
1199 rtx seq;
1200 rtx equiv_value;
1201 int ok = 0;
1203 /* Find the correct mode for the real and imaginary parts */
1204 enum machine_mode submode
1205 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1206 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1209 if (submode == BLKmode)
1210 abort ();
1212 if (! target)
1213 target = gen_reg_rtx (mode);
1215 start_sequence ();
1217 realr = gen_realpart (submode, target);
1218 imagr = gen_imagpart (submode, target);
1220 if (GET_MODE (op0) == mode)
1222 real0 = gen_realpart (submode, op0);
1223 imag0 = gen_imagpart (submode, op0);
1225 else
1226 real0 = op0;
1228 if (GET_MODE (op1) == mode)
1230 real1 = gen_realpart (submode, op1);
1231 imag1 = gen_imagpart (submode, op1);
1233 else
1234 real1 = op1;
1236 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1237 abort ();
1239 switch (binoptab->code)
1241 case PLUS:
1242 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1243 case MINUS:
1244 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1245 res = expand_binop (submode, binoptab, real0, real1,
1246 realr, unsignedp, methods);
1248 if (res == 0)
1249 break;
1250 else if (res != realr)
1251 emit_move_insn (realr, res);
1253 if (imag0 && imag1)
1254 res = expand_binop (submode, binoptab, imag0, imag1,
1255 imagr, unsignedp, methods);
1256 else if (imag0)
1257 res = imag0;
1258 else if (binoptab->code == MINUS)
1259 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1260 else
1261 res = imag1;
1263 if (res == 0)
1264 break;
1265 else if (res != imagr)
1266 emit_move_insn (imagr, res);
1268 ok = 1;
1269 break;
1271 case MULT:
1272 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1274 if (imag0 && imag1)
1276 rtx temp1, temp2;
1278 /* Don't fetch these from memory more than once. */
1279 real0 = force_reg (submode, real0);
1280 real1 = force_reg (submode, real1);
1281 imag0 = force_reg (submode, imag0);
1282 imag1 = force_reg (submode, imag1);
1284 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1285 unsignedp, methods);
1287 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1288 unsignedp, methods);
1290 if (temp1 == 0 || temp2 == 0)
1291 break;
1293 res = expand_binop (submode, sub_optab, temp1, temp2,
1294 realr, unsignedp, methods);
1296 if (res == 0)
1297 break;
1298 else if (res != realr)
1299 emit_move_insn (realr, res);
1301 temp1 = expand_binop (submode, binoptab, real0, imag1,
1302 NULL_RTX, unsignedp, methods);
1304 temp2 = expand_binop (submode, binoptab, real1, imag0,
1305 NULL_RTX, unsignedp, methods);
1307 if (temp1 == 0 || temp2 == 0)
1308 break;
1310 res = expand_binop (submode, add_optab, temp1, temp2,
1311 imagr, unsignedp, methods);
1313 if (res == 0)
1314 break;
1315 else if (res != imagr)
1316 emit_move_insn (imagr, res);
1318 ok = 1;
1320 else
1322 /* Don't fetch these from memory more than once. */
1323 real0 = force_reg (submode, real0);
1324 real1 = force_reg (submode, real1);
1326 res = expand_binop (submode, binoptab, real0, real1,
1327 realr, unsignedp, methods);
1328 if (res == 0)
1329 break;
1330 else if (res != realr)
1331 emit_move_insn (realr, res);
1333 if (imag0 != 0)
1334 res = expand_binop (submode, binoptab,
1335 real1, imag0, imagr, unsignedp, methods);
1336 else
1337 res = expand_binop (submode, binoptab,
1338 real0, imag1, imagr, unsignedp, methods);
1340 if (res == 0)
1341 break;
1342 else if (res != imagr)
1343 emit_move_insn (imagr, res);
1345 ok = 1;
1347 break;
1349 case DIV:
1350 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1352 if (imag1 == 0)
1354 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1356 /* Don't fetch these from memory more than once. */
1357 real1 = force_reg (submode, real1);
1359 /* Simply divide the real and imaginary parts by `c' */
1360 if (class == MODE_COMPLEX_FLOAT)
1361 res = expand_binop (submode, binoptab, real0, real1,
1362 realr, unsignedp, methods);
1363 else
1364 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1365 real0, real1, realr, unsignedp);
1367 if (res == 0)
1368 break;
1369 else if (res != realr)
1370 emit_move_insn (realr, res);
1372 if (class == MODE_COMPLEX_FLOAT)
1373 res = expand_binop (submode, binoptab, imag0, real1,
1374 imagr, unsignedp, methods);
1375 else
1376 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1377 imag0, real1, imagr, unsignedp);
1379 if (res == 0)
1380 break;
1381 else if (res != imagr)
1382 emit_move_insn (imagr, res);
1384 ok = 1;
1386 else
1388 /* Divisor is of complex type:
1389 X/(a+ib) */
1390 rtx divisor;
1391 rtx real_t, imag_t;
1392 rtx temp1, temp2;
1394 /* Don't fetch these from memory more than once. */
1395 real0 = force_reg (submode, real0);
1396 real1 = force_reg (submode, real1);
1398 if (imag0 != 0)
1399 imag0 = force_reg (submode, imag0);
1401 imag1 = force_reg (submode, imag1);
1403 /* Divisor: c*c + d*d */
1404 temp1 = expand_binop (submode, smul_optab, real1, real1,
1405 NULL_RTX, unsignedp, methods);
1407 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1408 NULL_RTX, unsignedp, methods);
1410 if (temp1 == 0 || temp2 == 0)
1411 break;
1413 divisor = expand_binop (submode, add_optab, temp1, temp2,
1414 NULL_RTX, unsignedp, methods);
1415 if (divisor == 0)
1416 break;
1418 if (imag0 == 0)
1420 /* ((a)(c-id))/divisor */
1421 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1423 /* Calculate the dividend */
1424 real_t = expand_binop (submode, smul_optab, real0, real1,
1425 NULL_RTX, unsignedp, methods);
1427 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1428 NULL_RTX, unsignedp, methods);
1430 if (real_t == 0 || imag_t == 0)
1431 break;
1433 imag_t = expand_unop (submode, neg_optab, imag_t,
1434 NULL_RTX, unsignedp);
1436 else
1438 /* ((a+ib)(c-id))/divider */
1439 /* Calculate the dividend */
1440 temp1 = expand_binop (submode, smul_optab, real0, real1,
1441 NULL_RTX, unsignedp, methods);
1443 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1444 NULL_RTX, unsignedp, methods);
1446 if (temp1 == 0 || temp2 == 0)
1447 break;
1449 real_t = expand_binop (submode, add_optab, temp1, temp2,
1450 NULL_RTX, unsignedp, methods);
1452 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1453 NULL_RTX, unsignedp, methods);
1455 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1456 NULL_RTX, unsignedp, methods);
1458 if (temp1 == 0 || temp2 == 0)
1459 break;
1461 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1462 NULL_RTX, unsignedp, methods);
1464 if (real_t == 0 || imag_t == 0)
1465 break;
1468 if (class == MODE_COMPLEX_FLOAT)
1469 res = expand_binop (submode, binoptab, real_t, divisor,
1470 realr, unsignedp, methods);
1471 else
1472 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1473 real_t, divisor, realr, unsignedp);
1475 if (res == 0)
1476 break;
1477 else if (res != realr)
1478 emit_move_insn (realr, res);
1480 if (class == MODE_COMPLEX_FLOAT)
1481 res = expand_binop (submode, binoptab, imag_t, divisor,
1482 imagr, unsignedp, methods);
1483 else
1484 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1485 imag_t, divisor, imagr, unsignedp);
1487 if (res == 0)
1488 break;
1489 else if (res != imagr)
1490 emit_move_insn (imagr, res);
1492 ok = 1;
1494 break;
1496 default:
1497 abort ();
1500 seq = get_insns ();
1501 end_sequence ();
1503 if (ok)
1505 if (binoptab->code != UNKNOWN)
1506 equiv_value
1507 = gen_rtx_fmt_ee (binoptab->code, mode,
1508 copy_rtx (op0), copy_rtx (op1));
1509 else
1510 equiv_value = 0;
1512 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1514 return target;
1518 /* It can't be open-coded in this mode.
1519 Use a library call if one is available and caller says that's ok. */
1521 if (binoptab->handlers[(int) mode].libfunc
1522 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1524 rtx insns;
1525 rtx op1x = op1;
1526 enum machine_mode op1_mode = mode;
1527 rtx value;
1529 start_sequence ();
1531 if (shift_op)
1533 op1_mode = word_mode;
1534 /* Specify unsigned here,
1535 since negative shift counts are meaningless. */
1536 op1x = convert_to_mode (word_mode, op1, 1);
1539 if (GET_MODE (op0) != VOIDmode
1540 && GET_MODE (op0) != mode)
1541 op0 = convert_to_mode (mode, op0, unsignedp);
1543 /* Pass 1 for NO_QUEUE so we don't lose any increments
1544 if the libcall is cse'd or moved. */
1545 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1546 NULL_RTX, 1, mode, 2,
1547 op0, mode, op1x, op1_mode);
1549 insns = get_insns ();
1550 end_sequence ();
1552 target = gen_reg_rtx (mode);
1553 emit_libcall_block (insns, target, value,
1554 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1556 return target;
1559 delete_insns_since (last);
1561 /* It can't be done in this mode. Can we do it in a wider mode? */
1563 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1564 || methods == OPTAB_MUST_WIDEN))
1566 /* Caller says, don't even try. */
1567 delete_insns_since (entry_last);
1568 return 0;
1571 /* Compute the value of METHODS to pass to recursive calls.
1572 Don't allow widening to be tried recursively. */
1574 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1576 /* Look for a wider mode of the same class for which it appears we can do
1577 the operation. */
1579 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1581 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1582 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1584 if ((binoptab->handlers[(int) wider_mode].insn_code
1585 != CODE_FOR_nothing)
1586 || (methods == OPTAB_LIB
1587 && binoptab->handlers[(int) wider_mode].libfunc))
1589 rtx xop0 = op0, xop1 = op1;
1590 int no_extend = 0;
1592 /* For certain integer operations, we need not actually extend
1593 the narrow operands, as long as we will truncate
1594 the results to the same narrowness. */
1596 if ((binoptab == ior_optab || binoptab == and_optab
1597 || binoptab == xor_optab
1598 || binoptab == add_optab || binoptab == sub_optab
1599 || binoptab == smul_optab || binoptab == ashl_optab)
1600 && class == MODE_INT)
1601 no_extend = 1;
1603 xop0 = widen_operand (xop0, wider_mode, mode,
1604 unsignedp, no_extend);
1606 /* The second operand of a shift must always be extended. */
1607 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1608 no_extend && binoptab != ashl_optab);
1610 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1611 unsignedp, methods);
1612 if (temp)
1614 if (class != MODE_INT)
1616 if (target == 0)
1617 target = gen_reg_rtx (mode);
1618 convert_move (target, temp, 0);
1619 return target;
1621 else
1622 return gen_lowpart (mode, temp);
1624 else
1625 delete_insns_since (last);
1630 delete_insns_since (entry_last);
1631 return 0;
1634 /* Expand a binary operator which has both signed and unsigned forms.
1635 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1636 signed operations.
1638 If we widen unsigned operands, we may use a signed wider operation instead
1639 of an unsigned wider operation, since the result would be the same. */
1642 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1643 enum machine_mode mode;
1644 optab uoptab, soptab;
1645 rtx op0, op1, target;
1646 int unsignedp;
1647 enum optab_methods methods;
1649 register rtx temp;
1650 optab direct_optab = unsignedp ? uoptab : soptab;
1651 struct optab wide_soptab;
1653 /* Do it without widening, if possible. */
1654 temp = expand_binop (mode, direct_optab, op0, op1, target,
1655 unsignedp, OPTAB_DIRECT);
1656 if (temp || methods == OPTAB_DIRECT)
1657 return temp;
1659 /* Try widening to a signed int. Make a fake signed optab that
1660 hides any signed insn for direct use. */
1661 wide_soptab = *soptab;
1662 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1663 wide_soptab.handlers[(int) mode].libfunc = 0;
1665 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1666 unsignedp, OPTAB_WIDEN);
1668 /* For unsigned operands, try widening to an unsigned int. */
1669 if (temp == 0 && unsignedp)
1670 temp = expand_binop (mode, uoptab, op0, op1, target,
1671 unsignedp, OPTAB_WIDEN);
1672 if (temp || methods == OPTAB_WIDEN)
1673 return temp;
1675 /* Use the right width lib call if that exists. */
1676 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1677 if (temp || methods == OPTAB_LIB)
1678 return temp;
1680 /* Must widen and use a lib call, use either signed or unsigned. */
1681 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1682 unsignedp, methods);
1683 if (temp != 0)
1684 return temp;
1685 if (unsignedp)
1686 return expand_binop (mode, uoptab, op0, op1, target,
1687 unsignedp, methods);
1688 return 0;
1691 /* Generate code to perform an operation specified by BINOPTAB
1692 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1693 We assume that the order of the operands for the instruction
1694 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1695 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1697 Either TARG0 or TARG1 may be zero, but what that means is that
1698 the result is not actually wanted. We will generate it into
1699 a dummy pseudo-reg and discard it. They may not both be zero.
1701 Returns 1 if this operation can be performed; 0 if not. */
1704 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1705 optab binoptab;
1706 rtx op0, op1;
1707 rtx targ0, targ1;
1708 int unsignedp;
1710 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1711 enum mode_class class;
1712 enum machine_mode wider_mode;
1713 rtx entry_last = get_last_insn ();
1714 rtx last;
1716 class = GET_MODE_CLASS (mode);
1718 op0 = protect_from_queue (op0, 0);
1719 op1 = protect_from_queue (op1, 0);
1721 if (flag_force_mem)
1723 op0 = force_not_mem (op0);
1724 op1 = force_not_mem (op1);
1727 /* If we are inside an appropriately-short loop and one operand is an
1728 expensive constant, force it into a register. */
1729 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1730 && rtx_cost (op0, binoptab->code) > 2)
1731 op0 = force_reg (mode, op0);
1733 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1734 && rtx_cost (op1, binoptab->code) > 2)
1735 op1 = force_reg (mode, op1);
1737 if (targ0)
1738 targ0 = protect_from_queue (targ0, 1);
1739 else
1740 targ0 = gen_reg_rtx (mode);
1741 if (targ1)
1742 targ1 = protect_from_queue (targ1, 1);
1743 else
1744 targ1 = gen_reg_rtx (mode);
1746 /* Record where to go back to if we fail. */
1747 last = get_last_insn ();
1749 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1751 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1752 enum machine_mode mode0 = insn_operand_mode[icode][1];
1753 enum machine_mode mode1 = insn_operand_mode[icode][2];
1754 rtx pat;
1755 rtx xop0 = op0, xop1 = op1;
1757 /* In case this insn wants input operands in modes different from the
1758 result, convert the operands. */
1759 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1760 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1762 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1763 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1765 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1766 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1767 xop0 = copy_to_mode_reg (mode0, xop0);
1769 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1770 xop1 = copy_to_mode_reg (mode1, xop1);
1772 /* We could handle this, but we should always be called with a pseudo
1773 for our targets and all insns should take them as outputs. */
1774 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1775 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1776 abort ();
1778 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1779 if (pat)
1781 emit_insn (pat);
1782 return 1;
1784 else
1785 delete_insns_since (last);
1788 /* It can't be done in this mode. Can we do it in a wider mode? */
1790 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1792 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1793 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1795 if (binoptab->handlers[(int) wider_mode].insn_code
1796 != CODE_FOR_nothing)
1798 register rtx t0 = gen_reg_rtx (wider_mode);
1799 register rtx t1 = gen_reg_rtx (wider_mode);
1801 if (expand_twoval_binop (binoptab,
1802 convert_modes (wider_mode, mode, op0,
1803 unsignedp),
1804 convert_modes (wider_mode, mode, op1,
1805 unsignedp),
1806 t0, t1, unsignedp))
1808 convert_move (targ0, t0, unsignedp);
1809 convert_move (targ1, t1, unsignedp);
1810 return 1;
1812 else
1813 delete_insns_since (last);
1818 delete_insns_since (entry_last);
1819 return 0;
1822 /* Generate code to perform an operation specified by UNOPTAB
1823 on operand OP0, with result having machine-mode MODE.
1825 UNSIGNEDP is for the case where we have to widen the operands
1826 to perform the operation. It says to use zero-extension.
1828 If TARGET is nonzero, the value
1829 is generated there, if it is convenient to do so.
1830 In all cases an rtx is returned for the locus of the value;
1831 this may or may not be TARGET. */
1834 expand_unop (mode, unoptab, op0, target, unsignedp)
1835 enum machine_mode mode;
1836 optab unoptab;
1837 rtx op0;
1838 rtx target;
1839 int unsignedp;
1841 enum mode_class class;
1842 enum machine_mode wider_mode;
1843 register rtx temp;
1844 rtx last = get_last_insn ();
1845 rtx pat;
1847 class = GET_MODE_CLASS (mode);
1849 op0 = protect_from_queue (op0, 0);
1851 if (flag_force_mem)
1853 op0 = force_not_mem (op0);
1856 if (target)
1857 target = protect_from_queue (target, 1);
1859 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1861 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1862 enum machine_mode mode0 = insn_operand_mode[icode][1];
1863 rtx xop0 = op0;
1865 if (target)
1866 temp = target;
1867 else
1868 temp = gen_reg_rtx (mode);
1870 if (GET_MODE (xop0) != VOIDmode
1871 && GET_MODE (xop0) != mode0)
1872 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1874 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1876 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1877 xop0 = copy_to_mode_reg (mode0, xop0);
1879 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1880 temp = gen_reg_rtx (mode);
1882 pat = GEN_FCN (icode) (temp, xop0);
1883 if (pat)
1885 if (GET_CODE (pat) == SEQUENCE
1886 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1888 delete_insns_since (last);
1889 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1892 emit_insn (pat);
1894 return temp;
1896 else
1897 delete_insns_since (last);
1900 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1902 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1903 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1904 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1906 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1908 rtx xop0 = op0;
1910 /* For certain operations, we need not actually extend
1911 the narrow operand, as long as we will truncate the
1912 results to the same narrowness. */
1914 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1915 (unoptab == neg_optab
1916 || unoptab == one_cmpl_optab)
1917 && class == MODE_INT);
1919 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1920 unsignedp);
1922 if (temp)
1924 if (class != MODE_INT)
1926 if (target == 0)
1927 target = gen_reg_rtx (mode);
1928 convert_move (target, temp, 0);
1929 return target;
1931 else
1932 return gen_lowpart (mode, temp);
1934 else
1935 delete_insns_since (last);
1939 /* These can be done a word at a time. */
1940 if (unoptab == one_cmpl_optab
1941 && class == MODE_INT
1942 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1943 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1945 int i;
1946 rtx insns;
1948 if (target == 0 || target == op0)
1949 target = gen_reg_rtx (mode);
1951 start_sequence ();
1953 /* Do the actual arithmetic. */
1954 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1956 rtx target_piece = operand_subword (target, i, 1, mode);
1957 rtx x = expand_unop (word_mode, unoptab,
1958 operand_subword_force (op0, i, mode),
1959 target_piece, unsignedp);
1960 if (target_piece != x)
1961 emit_move_insn (target_piece, x);
1964 insns = get_insns ();
1965 end_sequence ();
1967 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1968 gen_rtx_fmt_e (unoptab->code, mode,
1969 copy_rtx (op0)));
1970 return target;
1973 /* Open-code the complex negation operation. */
1974 else if (unoptab == neg_optab
1975 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1977 rtx target_piece;
1978 rtx x;
1979 rtx seq;
1981 /* Find the correct mode for the real and imaginary parts */
1982 enum machine_mode submode
1983 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1984 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1987 if (submode == BLKmode)
1988 abort ();
1990 if (target == 0)
1991 target = gen_reg_rtx (mode);
1993 start_sequence ();
1995 target_piece = gen_imagpart (submode, target);
1996 x = expand_unop (submode, unoptab,
1997 gen_imagpart (submode, op0),
1998 target_piece, unsignedp);
1999 if (target_piece != x)
2000 emit_move_insn (target_piece, x);
2002 target_piece = gen_realpart (submode, target);
2003 x = expand_unop (submode, unoptab,
2004 gen_realpart (submode, op0),
2005 target_piece, unsignedp);
2006 if (target_piece != x)
2007 emit_move_insn (target_piece, x);
2009 seq = get_insns ();
2010 end_sequence ();
2012 emit_no_conflict_block (seq, target, op0, 0,
2013 gen_rtx_fmt_e (unoptab->code, mode,
2014 copy_rtx (op0)));
2015 return target;
2018 /* Now try a library call in this mode. */
2019 if (unoptab->handlers[(int) mode].libfunc)
2021 rtx insns;
2022 rtx value;
2024 start_sequence ();
2026 /* Pass 1 for NO_QUEUE so we don't lose any increments
2027 if the libcall is cse'd or moved. */
2028 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2029 NULL_RTX, 1, mode, 1, op0, mode);
2030 insns = get_insns ();
2031 end_sequence ();
2033 target = gen_reg_rtx (mode);
2034 emit_libcall_block (insns, target, value,
2035 gen_rtx_fmt_e (unoptab->code, mode, op0));
2037 return target;
2040 /* It can't be done in this mode. Can we do it in a wider mode? */
2042 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2044 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2045 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2047 if ((unoptab->handlers[(int) wider_mode].insn_code
2048 != CODE_FOR_nothing)
2049 || unoptab->handlers[(int) wider_mode].libfunc)
2051 rtx xop0 = op0;
2053 /* For certain operations, we need not actually extend
2054 the narrow operand, as long as we will truncate the
2055 results to the same narrowness. */
2057 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2058 (unoptab == neg_optab
2059 || unoptab == one_cmpl_optab)
2060 && class == MODE_INT);
2062 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2063 unsignedp);
2065 if (temp)
2067 if (class != MODE_INT)
2069 if (target == 0)
2070 target = gen_reg_rtx (mode);
2071 convert_move (target, temp, 0);
2072 return target;
2074 else
2075 return gen_lowpart (mode, temp);
2077 else
2078 delete_insns_since (last);
2083 /* If there is no negate operation, try doing a subtract from zero.
2084 The US Software GOFAST library needs this. */
2085 if (unoptab == neg_optab)
2087 rtx temp;
2088 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2089 target, unsignedp, OPTAB_LIB_WIDEN);
2090 if (temp)
2091 return temp;
2094 return 0;
2097 /* Emit code to compute the absolute value of OP0, with result to
2098 TARGET if convenient. (TARGET may be 0.) The return value says
2099 where the result actually is to be found.
2101 MODE is the mode of the operand; the mode of the result is
2102 different but can be deduced from MODE.
2104 UNSIGNEDP is relevant if extension is needed. */
2107 expand_abs (mode, op0, target, unsignedp, safe)
2108 enum machine_mode mode;
2109 rtx op0;
2110 rtx target;
2111 int unsignedp;
2112 int safe;
2114 rtx temp, op1;
2116 /* First try to do it with a special abs instruction. */
2117 temp = expand_unop (mode, abs_optab, op0, target, 0);
2118 if (temp != 0)
2119 return temp;
2121 /* If this machine has expensive jumps, we can do integer absolute
2122 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2123 where W is the width of MODE. */
2125 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2127 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2128 size_int (GET_MODE_BITSIZE (mode) - 1),
2129 NULL_RTX, 0);
2131 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2132 OPTAB_LIB_WIDEN);
2133 if (temp != 0)
2134 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2135 OPTAB_LIB_WIDEN);
2137 if (temp != 0)
2138 return temp;
2141 /* If that does not win, use conditional jump and negate. */
2143 /* It is safe to use the target if it is the same
2144 as the source if this is also a pseudo register */
2145 if (op0 == target && GET_CODE (op0) == REG
2146 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2147 safe = 1;
2149 op1 = gen_label_rtx ();
2150 if (target == 0 || ! safe
2151 || GET_MODE (target) != mode
2152 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2153 || (GET_CODE (target) == REG
2154 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2155 target = gen_reg_rtx (mode);
2157 emit_move_insn (target, op0);
2158 NO_DEFER_POP;
2160 /* If this mode is an integer too wide to compare properly,
2161 compare word by word. Rely on CSE to optimize constant cases. */
2162 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2163 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2164 NULL_RTX, op1);
2165 else
2167 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2168 NULL_RTX, 0);
2169 if (temp == const1_rtx)
2170 return target;
2171 else if (temp != const0_rtx)
2173 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2174 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2175 else
2176 abort ();
2180 op0 = expand_unop (mode, neg_optab, target, target, 0);
2181 if (op0 != target)
2182 emit_move_insn (target, op0);
2183 emit_label (op1);
2184 OK_DEFER_POP;
2185 return target;
2188 /* Emit code to compute the absolute value of OP0, with result to
2189 TARGET if convenient. (TARGET may be 0.) The return value says
2190 where the result actually is to be found.
2192 MODE is the mode of the operand; the mode of the result is
2193 different but can be deduced from MODE.
2195 UNSIGNEDP is relevant for complex integer modes. */
2198 expand_complex_abs (mode, op0, target, unsignedp)
2199 enum machine_mode mode;
2200 rtx op0;
2201 rtx target;
2202 int unsignedp;
2204 enum mode_class class = GET_MODE_CLASS (mode);
2205 enum machine_mode wider_mode;
2206 register rtx temp;
2207 rtx entry_last = get_last_insn ();
2208 rtx last;
2209 rtx pat;
2211 /* Find the correct mode for the real and imaginary parts. */
2212 enum machine_mode submode
2213 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2214 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2217 if (submode == BLKmode)
2218 abort ();
2220 op0 = protect_from_queue (op0, 0);
2222 if (flag_force_mem)
2224 op0 = force_not_mem (op0);
2227 last = get_last_insn ();
2229 if (target)
2230 target = protect_from_queue (target, 1);
2232 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2234 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2235 enum machine_mode mode0 = insn_operand_mode[icode][1];
2236 rtx xop0 = op0;
2238 if (target)
2239 temp = target;
2240 else
2241 temp = gen_reg_rtx (submode);
2243 if (GET_MODE (xop0) != VOIDmode
2244 && GET_MODE (xop0) != mode0)
2245 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2247 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2249 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2250 xop0 = copy_to_mode_reg (mode0, xop0);
2252 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2253 temp = gen_reg_rtx (submode);
2255 pat = GEN_FCN (icode) (temp, xop0);
2256 if (pat)
2258 if (GET_CODE (pat) == SEQUENCE
2259 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2261 delete_insns_since (last);
2262 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2265 emit_insn (pat);
2267 return temp;
2269 else
2270 delete_insns_since (last);
2273 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2275 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2276 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2278 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2280 rtx xop0 = op0;
2282 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2283 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2285 if (temp)
2287 if (class != MODE_COMPLEX_INT)
2289 if (target == 0)
2290 target = gen_reg_rtx (submode);
2291 convert_move (target, temp, 0);
2292 return target;
2294 else
2295 return gen_lowpart (submode, temp);
2297 else
2298 delete_insns_since (last);
2302 /* Open-code the complex absolute-value operation
2303 if we can open-code sqrt. Otherwise it's not worth while. */
2304 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2306 rtx real, imag, total;
2308 real = gen_realpart (submode, op0);
2309 imag = gen_imagpart (submode, op0);
2311 /* Square both parts. */
2312 real = expand_mult (submode, real, real, NULL_RTX, 0);
2313 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2315 /* Sum the parts. */
2316 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2317 0, OPTAB_LIB_WIDEN);
2319 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2320 target = expand_unop (submode, sqrt_optab, total, target, 0);
2321 if (target == 0)
2322 delete_insns_since (last);
2323 else
2324 return target;
2327 /* Now try a library call in this mode. */
2328 if (abs_optab->handlers[(int) mode].libfunc)
2330 rtx insns;
2331 rtx value;
2333 start_sequence ();
2335 /* Pass 1 for NO_QUEUE so we don't lose any increments
2336 if the libcall is cse'd or moved. */
2337 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2338 NULL_RTX, 1, submode, 1, op0, mode);
2339 insns = get_insns ();
2340 end_sequence ();
2342 target = gen_reg_rtx (submode);
2343 emit_libcall_block (insns, target, value,
2344 gen_rtx_fmt_e (abs_optab->code, mode, op0));
2346 return target;
2349 /* It can't be done in this mode. Can we do it in a wider mode? */
2351 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2352 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2354 if ((abs_optab->handlers[(int) wider_mode].insn_code
2355 != CODE_FOR_nothing)
2356 || abs_optab->handlers[(int) wider_mode].libfunc)
2358 rtx xop0 = op0;
2360 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2362 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2364 if (temp)
2366 if (class != MODE_COMPLEX_INT)
2368 if (target == 0)
2369 target = gen_reg_rtx (submode);
2370 convert_move (target, temp, 0);
2371 return target;
2373 else
2374 return gen_lowpart (submode, temp);
2376 else
2377 delete_insns_since (last);
2381 delete_insns_since (entry_last);
2382 return 0;
2385 /* Generate an instruction whose insn-code is INSN_CODE,
2386 with two operands: an output TARGET and an input OP0.
2387 TARGET *must* be nonzero, and the output is always stored there.
2388 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2389 the value that is stored into TARGET. */
2391 void
2392 emit_unop_insn (icode, target, op0, code)
2393 int icode;
2394 rtx target;
2395 rtx op0;
2396 enum rtx_code code;
2398 register rtx temp;
2399 enum machine_mode mode0 = insn_operand_mode[icode][1];
2400 rtx pat;
2402 temp = target = protect_from_queue (target, 1);
2404 op0 = protect_from_queue (op0, 0);
2406 /* Sign and zero extension from memory is often done specially on
2407 RISC machines, so forcing into a register here can pessimize
2408 code. */
2409 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2410 op0 = force_not_mem (op0);
2412 /* Now, if insn does not accept our operands, put them into pseudos. */
2414 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2415 op0 = copy_to_mode_reg (mode0, op0);
2417 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2418 || (flag_force_mem && GET_CODE (temp) == MEM))
2419 temp = gen_reg_rtx (GET_MODE (temp));
2421 pat = GEN_FCN (icode) (temp, op0);
2423 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2424 add_equal_note (pat, temp, code, op0, NULL_RTX);
2426 emit_insn (pat);
2428 if (temp != target)
2429 emit_move_insn (target, temp);
2432 /* Emit code to perform a series of operations on a multi-word quantity, one
2433 word at a time.
2435 Such a block is preceded by a CLOBBER of the output, consists of multiple
2436 insns, each setting one word of the output, and followed by a SET copying
2437 the output to itself.
2439 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2440 note indicating that it doesn't conflict with the (also multi-word)
2441 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2442 notes.
2444 INSNS is a block of code generated to perform the operation, not including
2445 the CLOBBER and final copy. All insns that compute intermediate values
2446 are first emitted, followed by the block as described above.
2448 TARGET, OP0, and OP1 are the output and inputs of the operations,
2449 respectively. OP1 may be zero for a unary operation.
2451 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2452 on the last insn.
2454 If TARGET is not a register, INSNS is simply emitted with no special
2455 processing. Likewise if anything in INSNS is not an INSN or if
2456 there is a libcall block inside INSNS.
2458 The final insn emitted is returned. */
2461 emit_no_conflict_block (insns, target, op0, op1, equiv)
2462 rtx insns;
2463 rtx target;
2464 rtx op0, op1;
2465 rtx equiv;
2467 rtx prev, next, first, last, insn;
2469 if (GET_CODE (target) != REG || reload_in_progress)
2470 return emit_insns (insns);
2471 else
2472 for (insn = insns; insn; insn = NEXT_INSN (insn))
2473 if (GET_CODE (insn) != INSN
2474 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2475 return emit_insns (insns);
2477 /* First emit all insns that do not store into words of the output and remove
2478 these from the list. */
2479 for (insn = insns; insn; insn = next)
2481 rtx set = 0;
2482 int i;
2484 next = NEXT_INSN (insn);
2486 if (GET_CODE (PATTERN (insn)) == SET)
2487 set = PATTERN (insn);
2488 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2490 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2491 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2493 set = XVECEXP (PATTERN (insn), 0, i);
2494 break;
2498 if (set == 0)
2499 abort ();
2501 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2503 if (PREV_INSN (insn))
2504 NEXT_INSN (PREV_INSN (insn)) = next;
2505 else
2506 insns = next;
2508 if (next)
2509 PREV_INSN (next) = PREV_INSN (insn);
2511 add_insn (insn);
2515 prev = get_last_insn ();
2517 /* Now write the CLOBBER of the output, followed by the setting of each
2518 of the words, followed by the final copy. */
2519 if (target != op0 && target != op1)
2520 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2522 for (insn = insns; insn; insn = next)
2524 next = NEXT_INSN (insn);
2525 add_insn (insn);
2527 if (op1 && GET_CODE (op1) == REG)
2528 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2529 REG_NOTES (insn));
2531 if (op0 && GET_CODE (op0) == REG)
2532 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2533 REG_NOTES (insn));
2536 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2537 != CODE_FOR_nothing)
2539 last = emit_move_insn (target, target);
2540 if (equiv)
2541 REG_NOTES (last)
2542 = gen_rtx_EXPR_LIST (REG_EQUAL, equiv, REG_NOTES (last));
2544 else
2545 last = get_last_insn ();
2547 if (prev == 0)
2548 first = get_insns ();
2549 else
2550 first = NEXT_INSN (prev);
2552 /* Encapsulate the block so it gets manipulated as a unit. */
2553 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2554 REG_NOTES (first));
2555 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2557 return last;
2560 /* Emit code to make a call to a constant function or a library call.
2562 INSNS is a list containing all insns emitted in the call.
2563 These insns leave the result in RESULT. Our block is to copy RESULT
2564 to TARGET, which is logically equivalent to EQUIV.
2566 We first emit any insns that set a pseudo on the assumption that these are
2567 loading constants into registers; doing so allows them to be safely cse'ed
2568 between blocks. Then we emit all the other insns in the block, followed by
2569 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2570 note with an operand of EQUIV.
2572 Moving assignments to pseudos outside of the block is done to improve
2573 the generated code, but is not required to generate correct code,
2574 hence being unable to move an assignment is not grounds for not making
2575 a libcall block. There are two reasons why it is safe to leave these
2576 insns inside the block: First, we know that these pseudos cannot be
2577 used in generated RTL outside the block since they are created for
2578 temporary purposes within the block. Second, CSE will not record the
2579 values of anything set inside a libcall block, so we know they must
2580 be dead at the end of the block.
2582 Except for the first group of insns (the ones setting pseudos), the
2583 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2585 void
2586 emit_libcall_block (insns, target, result, equiv)
2587 rtx insns;
2588 rtx target;
2589 rtx result;
2590 rtx equiv;
2592 rtx prev, next, first, last, insn;
2594 /* First emit all insns that set pseudos. Remove them from the list as
2595 we go. Avoid insns that set pseudos which were referenced in previous
2596 insns. These can be generated by move_by_pieces, for example,
2597 to update an address. Similarly, avoid insns that reference things
2598 set in previous insns. */
2600 for (insn = insns; insn; insn = next)
2602 rtx set = single_set (insn);
2604 next = NEXT_INSN (insn);
2606 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2607 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2608 && (insn == insns
2609 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2610 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2611 && ! modified_in_p (SET_SRC (set), insns)
2612 && ! modified_between_p (SET_SRC (set), insns, insn))))
2614 if (PREV_INSN (insn))
2615 NEXT_INSN (PREV_INSN (insn)) = next;
2616 else
2617 insns = next;
2619 if (next)
2620 PREV_INSN (next) = PREV_INSN (insn);
2622 add_insn (insn);
2626 prev = get_last_insn ();
2628 /* Write the remaining insns followed by the final copy. */
2630 for (insn = insns; insn; insn = next)
2632 next = NEXT_INSN (insn);
2634 add_insn (insn);
2637 last = emit_move_insn (target, result);
2638 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2639 != CODE_FOR_nothing)
2640 REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (equiv),
2641 REG_NOTES (last));
2643 if (prev == 0)
2644 first = get_insns ();
2645 else
2646 first = NEXT_INSN (prev);
2648 /* Encapsulate the block so it gets manipulated as a unit. */
2649 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2650 REG_NOTES (first));
2651 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2654 /* Generate code to store zero in X. */
2656 void
2657 emit_clr_insn (x)
2658 rtx x;
2660 emit_move_insn (x, const0_rtx);
2663 /* Generate code to store 1 in X
2664 assuming it contains zero beforehand. */
2666 void
2667 emit_0_to_1_insn (x)
2668 rtx x;
2670 emit_move_insn (x, const1_rtx);
2673 /* Generate code to compare X with Y
2674 so that the condition codes are set.
2676 MODE is the mode of the inputs (in case they are const_int).
2677 UNSIGNEDP nonzero says that X and Y are unsigned;
2678 this matters if they need to be widened.
2680 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2681 and ALIGN specifies the known shared alignment of X and Y.
2683 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2684 It is ignored for fixed-point and block comparisons;
2685 it is used only for floating-point comparisons. */
2687 void
2688 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2689 rtx x, y;
2690 enum rtx_code comparison;
2691 rtx size;
2692 enum machine_mode mode;
2693 int unsignedp;
2694 int align;
2696 enum mode_class class;
2697 enum machine_mode wider_mode;
2699 class = GET_MODE_CLASS (mode);
2701 /* They could both be VOIDmode if both args are immediate constants,
2702 but we should fold that at an earlier stage.
2703 With no special code here, this will call abort,
2704 reminding the programmer to implement such folding. */
2706 if (mode != BLKmode && flag_force_mem)
2708 x = force_not_mem (x);
2709 y = force_not_mem (y);
2712 /* If we are inside an appropriately-short loop and one operand is an
2713 expensive constant, force it into a register. */
2714 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2715 x = force_reg (mode, x);
2717 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2718 y = force_reg (mode, y);
2720 /* Don't let both operands fail to indicate the mode. */
2721 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2722 x = force_reg (mode, x);
2724 /* Handle all BLKmode compares. */
2726 if (mode == BLKmode)
2728 emit_queue ();
2729 x = protect_from_queue (x, 0);
2730 y = protect_from_queue (y, 0);
2732 if (size == 0)
2733 abort ();
2734 #ifdef HAVE_cmpstrqi
2735 if (HAVE_cmpstrqi
2736 && GET_CODE (size) == CONST_INT
2737 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2739 enum machine_mode result_mode
2740 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2741 rtx result = gen_reg_rtx (result_mode);
2742 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2743 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2744 result_mode, 0, 0);
2746 else
2747 #endif
2748 #ifdef HAVE_cmpstrhi
2749 if (HAVE_cmpstrhi
2750 && GET_CODE (size) == CONST_INT
2751 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2753 enum machine_mode result_mode
2754 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2755 rtx result = gen_reg_rtx (result_mode);
2756 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2757 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2758 result_mode, 0, 0);
2760 else
2761 #endif
2762 #ifdef HAVE_cmpstrsi
2763 if (HAVE_cmpstrsi)
2765 enum machine_mode result_mode
2766 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2767 rtx result = gen_reg_rtx (result_mode);
2768 size = protect_from_queue (size, 0);
2769 emit_insn (gen_cmpstrsi (result, x, y,
2770 convert_to_mode (SImode, size, 1),
2771 GEN_INT (align)));
2772 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2773 result_mode, 0, 0);
2775 else
2776 #endif
2778 rtx result;
2780 #ifdef TARGET_MEM_FUNCTIONS
2781 emit_library_call (memcmp_libfunc, 0,
2782 TYPE_MODE (integer_type_node), 3,
2783 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2784 convert_to_mode (TYPE_MODE (sizetype), size,
2785 TREE_UNSIGNED (sizetype)),
2786 TYPE_MODE (sizetype));
2787 #else
2788 emit_library_call (bcmp_libfunc, 0,
2789 TYPE_MODE (integer_type_node), 3,
2790 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2791 convert_to_mode (TYPE_MODE (integer_type_node),
2792 size,
2793 TREE_UNSIGNED (integer_type_node)),
2794 TYPE_MODE (integer_type_node));
2795 #endif
2797 /* Immediately move the result of the libcall into a pseudo
2798 register so reload doesn't clobber the value if it needs
2799 the return register for a spill reg. */
2800 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
2801 emit_move_insn (result,
2802 hard_libcall_value (TYPE_MODE (integer_type_node)));
2803 emit_cmp_insn (result,
2804 const0_rtx, comparison, NULL_RTX,
2805 TYPE_MODE (integer_type_node), 0, 0);
2807 return;
2810 /* Handle some compares against zero. */
2812 if (y == CONST0_RTX (mode)
2813 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2815 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2817 emit_queue ();
2818 x = protect_from_queue (x, 0);
2819 y = protect_from_queue (y, 0);
2821 /* Now, if insn does accept these operands, put them into pseudos. */
2822 if (! (*insn_operand_predicate[icode][0])
2823 (x, insn_operand_mode[icode][0]))
2824 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2826 emit_insn (GEN_FCN (icode) (x));
2827 return;
2830 /* Handle compares for which there is a directly suitable insn. */
2832 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2834 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2836 emit_queue ();
2837 x = protect_from_queue (x, 0);
2838 y = protect_from_queue (y, 0);
2840 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2841 if (! (*insn_operand_predicate[icode][0])
2842 (x, insn_operand_mode[icode][0]))
2843 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2845 if (! (*insn_operand_predicate[icode][1])
2846 (y, insn_operand_mode[icode][1]))
2847 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2849 emit_insn (GEN_FCN (icode) (x, y));
2850 return;
2853 /* Try widening if we can find a direct insn that way. */
2855 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2857 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2858 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2860 if (cmp_optab->handlers[(int) wider_mode].insn_code
2861 != CODE_FOR_nothing)
2863 x = protect_from_queue (x, 0);
2864 y = protect_from_queue (y, 0);
2865 x = convert_modes (wider_mode, mode, x, unsignedp);
2866 y = convert_modes (wider_mode, mode, y, unsignedp);
2867 emit_cmp_insn (x, y, comparison, NULL_RTX,
2868 wider_mode, unsignedp, align);
2869 return;
2874 /* Handle a lib call just for the mode we are using. */
2876 if (cmp_optab->handlers[(int) mode].libfunc
2877 && class != MODE_FLOAT)
2879 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2880 rtx result;
2882 /* If we want unsigned, and this mode has a distinct unsigned
2883 comparison routine, use that. */
2884 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2885 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2887 emit_library_call (libfunc, 1,
2888 word_mode, 2, x, mode, y, mode);
2890 /* Immediately move the result of the libcall into a pseudo
2891 register so reload doesn't clobber the value if it needs
2892 the return register for a spill reg. */
2893 result = gen_reg_rtx (word_mode);
2894 emit_move_insn (result, hard_libcall_value (word_mode));
2896 /* Integer comparison returns a result that must be compared against 1,
2897 so that even if we do an unsigned compare afterward,
2898 there is still a value that can represent the result "less than". */
2899 emit_cmp_insn (result, const1_rtx,
2900 comparison, NULL_RTX, word_mode, unsignedp, 0);
2901 return;
2904 if (class == MODE_FLOAT)
2905 emit_float_lib_cmp (x, y, comparison);
2907 else
2908 abort ();
2911 /* Nonzero if a compare of mode MODE can be done straightforwardly
2912 (without splitting it into pieces). */
2915 can_compare_p (mode)
2916 enum machine_mode mode;
2920 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2921 return 1;
2922 mode = GET_MODE_WIDER_MODE (mode);
2923 } while (mode != VOIDmode);
2925 return 0;
2928 /* Emit a library call comparison between floating point X and Y.
2929 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2931 void
2932 emit_float_lib_cmp (x, y, comparison)
2933 rtx x, y;
2934 enum rtx_code comparison;
2936 enum machine_mode mode = GET_MODE (x);
2937 rtx libfunc = 0;
2938 rtx result;
2940 if (mode == HFmode)
2941 switch (comparison)
2943 case EQ:
2944 libfunc = eqhf2_libfunc;
2945 break;
2947 case NE:
2948 libfunc = nehf2_libfunc;
2949 break;
2951 case GT:
2952 libfunc = gthf2_libfunc;
2953 break;
2955 case GE:
2956 libfunc = gehf2_libfunc;
2957 break;
2959 case LT:
2960 libfunc = lthf2_libfunc;
2961 break;
2963 case LE:
2964 libfunc = lehf2_libfunc;
2965 break;
2967 default:
2968 break;
2970 else if (mode == SFmode)
2971 switch (comparison)
2973 case EQ:
2974 libfunc = eqsf2_libfunc;
2975 break;
2977 case NE:
2978 libfunc = nesf2_libfunc;
2979 break;
2981 case GT:
2982 libfunc = gtsf2_libfunc;
2983 break;
2985 case GE:
2986 libfunc = gesf2_libfunc;
2987 break;
2989 case LT:
2990 libfunc = ltsf2_libfunc;
2991 break;
2993 case LE:
2994 libfunc = lesf2_libfunc;
2995 break;
2997 default:
2998 break;
3000 else if (mode == DFmode)
3001 switch (comparison)
3003 case EQ:
3004 libfunc = eqdf2_libfunc;
3005 break;
3007 case NE:
3008 libfunc = nedf2_libfunc;
3009 break;
3011 case GT:
3012 libfunc = gtdf2_libfunc;
3013 break;
3015 case GE:
3016 libfunc = gedf2_libfunc;
3017 break;
3019 case LT:
3020 libfunc = ltdf2_libfunc;
3021 break;
3023 case LE:
3024 libfunc = ledf2_libfunc;
3025 break;
3027 default:
3028 break;
3030 else if (mode == XFmode)
3031 switch (comparison)
3033 case EQ:
3034 libfunc = eqxf2_libfunc;
3035 break;
3037 case NE:
3038 libfunc = nexf2_libfunc;
3039 break;
3041 case GT:
3042 libfunc = gtxf2_libfunc;
3043 break;
3045 case GE:
3046 libfunc = gexf2_libfunc;
3047 break;
3049 case LT:
3050 libfunc = ltxf2_libfunc;
3051 break;
3053 case LE:
3054 libfunc = lexf2_libfunc;
3055 break;
3057 default:
3058 break;
3060 else if (mode == TFmode)
3061 switch (comparison)
3063 case EQ:
3064 libfunc = eqtf2_libfunc;
3065 break;
3067 case NE:
3068 libfunc = netf2_libfunc;
3069 break;
3071 case GT:
3072 libfunc = gttf2_libfunc;
3073 break;
3075 case GE:
3076 libfunc = getf2_libfunc;
3077 break;
3079 case LT:
3080 libfunc = lttf2_libfunc;
3081 break;
3083 case LE:
3084 libfunc = letf2_libfunc;
3085 break;
3087 default:
3088 break;
3090 else
3092 enum machine_mode wider_mode;
3094 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3095 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3097 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3098 != CODE_FOR_nothing)
3099 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3101 x = protect_from_queue (x, 0);
3102 y = protect_from_queue (y, 0);
3103 x = convert_to_mode (wider_mode, x, 0);
3104 y = convert_to_mode (wider_mode, y, 0);
3105 emit_float_lib_cmp (x, y, comparison);
3106 return;
3109 abort ();
3112 if (libfunc == 0)
3113 abort ();
3115 emit_library_call (libfunc, 1,
3116 word_mode, 2, x, mode, y, mode);
3118 /* Immediately move the result of the libcall into a pseudo
3119 register so reload doesn't clobber the value if it needs
3120 the return register for a spill reg. */
3121 result = gen_reg_rtx (word_mode);
3122 emit_move_insn (result, hard_libcall_value (word_mode));
3124 emit_cmp_insn (result, const0_rtx, comparison,
3125 NULL_RTX, word_mode, 0, 0);
3128 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3130 void
3131 emit_indirect_jump (loc)
3132 rtx loc;
3134 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3135 (loc, Pmode)))
3136 loc = copy_to_mode_reg (Pmode, loc);
3138 emit_jump_insn (gen_indirect_jump (loc));
3139 emit_barrier ();
3142 #ifdef HAVE_conditional_move
3144 /* Emit a conditional move instruction if the machine supports one for that
3145 condition and machine mode.
3147 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3148 the mode to use should they be constants. If it is VOIDmode, they cannot
3149 both be constants.
3151 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3152 should be stored there. MODE is the mode to use should they be constants.
3153 If it is VOIDmode, they cannot both be constants.
3155 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3156 is not supported. */
3159 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3160 unsignedp)
3161 rtx target;
3162 enum rtx_code code;
3163 rtx op0, op1;
3164 enum machine_mode cmode;
3165 rtx op2, op3;
3166 enum machine_mode mode;
3167 int unsignedp;
3169 rtx tem, subtarget, comparison, insn;
3170 enum insn_code icode;
3172 /* If one operand is constant, make it the second one. Only do this
3173 if the other operand is not constant as well. */
3175 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3176 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3178 tem = op0;
3179 op0 = op1;
3180 op1 = tem;
3181 code = swap_condition (code);
3184 if (cmode == VOIDmode)
3185 cmode = GET_MODE (op0);
3187 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3188 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3189 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3190 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3192 tem = op2;
3193 op2 = op3;
3194 op3 = tem;
3195 code = reverse_condition (code);
3198 if (mode == VOIDmode)
3199 mode = GET_MODE (op2);
3201 icode = movcc_gen_code[mode];
3203 if (icode == CODE_FOR_nothing)
3204 return 0;
3206 if (flag_force_mem)
3208 op2 = force_not_mem (op2);
3209 op3 = force_not_mem (op3);
3212 if (target)
3213 target = protect_from_queue (target, 1);
3214 else
3215 target = gen_reg_rtx (mode);
3217 subtarget = target;
3219 emit_queue ();
3221 op2 = protect_from_queue (op2, 0);
3222 op3 = protect_from_queue (op3, 0);
3224 /* If the insn doesn't accept these operands, put them in pseudos. */
3226 if (! (*insn_operand_predicate[icode][0])
3227 (subtarget, insn_operand_mode[icode][0]))
3228 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3230 if (! (*insn_operand_predicate[icode][2])
3231 (op2, insn_operand_mode[icode][2]))
3232 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3234 if (! (*insn_operand_predicate[icode][3])
3235 (op3, insn_operand_mode[icode][3]))
3236 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3238 /* Everything should now be in the suitable form, so emit the compare insn
3239 and then the conditional move. */
3241 comparison
3242 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3244 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3245 if (GET_CODE (comparison) != code)
3246 /* This shouldn't happen. */
3247 abort ();
3249 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3251 /* If that failed, then give up. */
3252 if (insn == 0)
3253 return 0;
3255 emit_insn (insn);
3257 if (subtarget != target)
3258 convert_move (target, subtarget, 0);
3260 return target;
3263 /* Return non-zero if a conditional move of mode MODE is supported.
3265 This function is for combine so it can tell whether an insn that looks
3266 like a conditional move is actually supported by the hardware. If we
3267 guess wrong we lose a bit on optimization, but that's it. */
3268 /* ??? sparc64 supports conditionally moving integers values based on fp
3269 comparisons, and vice versa. How do we handle them? */
3272 can_conditionally_move_p (mode)
3273 enum machine_mode mode;
3275 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3276 return 1;
3278 return 0;
3281 #endif /* HAVE_conditional_move */
3283 /* These three functions generate an insn body and return it
3284 rather than emitting the insn.
3286 They do not protect from queued increments,
3287 because they may be used 1) in protect_from_queue itself
3288 and 2) in other passes where there is no queue. */
3290 /* Generate and return an insn body to add Y to X. */
3293 gen_add2_insn (x, y)
3294 rtx x, y;
3296 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3298 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3299 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3300 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3301 abort ();
3303 return (GEN_FCN (icode) (x, x, y));
3307 have_add2_insn (mode)
3308 enum machine_mode mode;
3310 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3313 /* Generate and return an insn body to subtract Y from X. */
3316 gen_sub2_insn (x, y)
3317 rtx x, y;
3319 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3321 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3322 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3323 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3324 abort ();
3326 return (GEN_FCN (icode) (x, x, y));
3330 have_sub2_insn (mode)
3331 enum machine_mode mode;
3333 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3336 /* Generate the body of an instruction to copy Y into X.
3337 It may be a SEQUENCE, if one insn isn't enough. */
3340 gen_move_insn (x, y)
3341 rtx x, y;
3343 register enum machine_mode mode = GET_MODE (x);
3344 enum insn_code insn_code;
3345 rtx seq;
3347 if (mode == VOIDmode)
3348 mode = GET_MODE (y);
3350 insn_code = mov_optab->handlers[(int) mode].insn_code;
3352 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3353 find a mode to do it in. If we have a movcc, use it. Otherwise,
3354 find the MODE_INT mode of the same width. */
3356 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3358 enum machine_mode tmode = VOIDmode;
3359 rtx x1 = x, y1 = y;
3361 if (mode != CCmode
3362 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3363 tmode = CCmode;
3364 else
3365 for (tmode = QImode; tmode != VOIDmode;
3366 tmode = GET_MODE_WIDER_MODE (tmode))
3367 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3368 break;
3370 if (tmode == VOIDmode)
3371 abort ();
3373 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3374 may call change_address which is not appropriate if we were
3375 called when a reload was in progress. We don't have to worry
3376 about changing the address since the size in bytes is supposed to
3377 be the same. Copy the MEM to change the mode and move any
3378 substitutions from the old MEM to the new one. */
3380 if (reload_in_progress)
3382 x = gen_lowpart_common (tmode, x1);
3383 if (x == 0 && GET_CODE (x1) == MEM)
3385 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3386 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3387 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3388 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3389 copy_replacements (x1, x);
3392 y = gen_lowpart_common (tmode, y1);
3393 if (y == 0 && GET_CODE (y1) == MEM)
3395 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3396 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3397 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3398 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3399 copy_replacements (y1, y);
3402 else
3404 x = gen_lowpart (tmode, x);
3405 y = gen_lowpart (tmode, y);
3408 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3409 return (GEN_FCN (insn_code) (x, y));
3412 start_sequence ();
3413 emit_move_insn_1 (x, y);
3414 seq = gen_sequence ();
3415 end_sequence ();
3416 return seq;
3419 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3420 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3421 no such operation exists, CODE_FOR_nothing will be returned. */
3423 enum insn_code
3424 can_extend_p (to_mode, from_mode, unsignedp)
3425 enum machine_mode to_mode, from_mode;
3426 int unsignedp;
3428 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3431 /* Generate the body of an insn to extend Y (with mode MFROM)
3432 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3435 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3436 rtx x, y;
3437 enum machine_mode mto, mfrom;
3438 int unsignedp;
3440 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3443 /* can_fix_p and can_float_p say whether the target machine
3444 can directly convert a given fixed point type to
3445 a given floating point type, or vice versa.
3446 The returned value is the CODE_FOR_... value to use,
3447 or CODE_FOR_nothing if these modes cannot be directly converted.
3449 *TRUNCP_PTR is set to 1 if it is necessary to output
3450 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3452 static enum insn_code
3453 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3454 enum machine_mode fltmode, fixmode;
3455 int unsignedp;
3456 int *truncp_ptr;
3458 *truncp_ptr = 0;
3459 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3460 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3462 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3464 *truncp_ptr = 1;
3465 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3467 return CODE_FOR_nothing;
3470 static enum insn_code
3471 can_float_p (fltmode, fixmode, unsignedp)
3472 enum machine_mode fixmode, fltmode;
3473 int unsignedp;
3475 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3478 /* Generate code to convert FROM to floating point
3479 and store in TO. FROM must be fixed point and not VOIDmode.
3480 UNSIGNEDP nonzero means regard FROM as unsigned.
3481 Normally this is done by correcting the final value
3482 if it is negative. */
3484 void
3485 expand_float (to, from, unsignedp)
3486 rtx to, from;
3487 int unsignedp;
3489 enum insn_code icode;
3490 register rtx target = to;
3491 enum machine_mode fmode, imode;
3493 /* Crash now, because we won't be able to decide which mode to use. */
3494 if (GET_MODE (from) == VOIDmode)
3495 abort ();
3497 /* Look for an insn to do the conversion. Do it in the specified
3498 modes if possible; otherwise convert either input, output or both to
3499 wider mode. If the integer mode is wider than the mode of FROM,
3500 we can do the conversion signed even if the input is unsigned. */
3502 for (imode = GET_MODE (from); imode != VOIDmode;
3503 imode = GET_MODE_WIDER_MODE (imode))
3504 for (fmode = GET_MODE (to); fmode != VOIDmode;
3505 fmode = GET_MODE_WIDER_MODE (fmode))
3507 int doing_unsigned = unsignedp;
3509 icode = can_float_p (fmode, imode, unsignedp);
3510 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3511 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3513 if (icode != CODE_FOR_nothing)
3515 to = protect_from_queue (to, 1);
3516 from = protect_from_queue (from, 0);
3518 if (imode != GET_MODE (from))
3519 from = convert_to_mode (imode, from, unsignedp);
3521 if (fmode != GET_MODE (to))
3522 target = gen_reg_rtx (fmode);
3524 emit_unop_insn (icode, target, from,
3525 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3527 if (target != to)
3528 convert_move (to, target, 0);
3529 return;
3533 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3535 /* Unsigned integer, and no way to convert directly.
3536 Convert as signed, then conditionally adjust the result. */
3537 if (unsignedp)
3539 rtx label = gen_label_rtx ();
3540 rtx temp;
3541 REAL_VALUE_TYPE offset;
3543 emit_queue ();
3545 to = protect_from_queue (to, 1);
3546 from = protect_from_queue (from, 0);
3548 if (flag_force_mem)
3549 from = force_not_mem (from);
3551 /* Look for a usable floating mode FMODE wider than the source and at
3552 least as wide as the target. Using FMODE will avoid rounding woes
3553 with unsigned values greater than the signed maximum value. */
3555 for (fmode = GET_MODE (to); fmode != VOIDmode;
3556 fmode = GET_MODE_WIDER_MODE (fmode))
3557 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3558 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3559 break;
3561 if (fmode == VOIDmode)
3563 /* There is no such mode. Pretend the target is wide enough. */
3564 fmode = GET_MODE (to);
3566 /* Avoid double-rounding when TO is narrower than FROM. */
3567 if ((significand_size (fmode) + 1)
3568 < GET_MODE_BITSIZE (GET_MODE (from)))
3570 rtx temp1;
3571 rtx neglabel = gen_label_rtx ();
3573 /* Don't use TARGET if it isn't a register, is a hard register,
3574 or is the wrong mode. */
3575 if (GET_CODE (target) != REG
3576 || REGNO (target) < FIRST_PSEUDO_REGISTER
3577 || GET_MODE (target) != fmode)
3578 target = gen_reg_rtx (fmode);
3580 imode = GET_MODE (from);
3581 do_pending_stack_adjust ();
3583 /* Test whether the sign bit is set. */
3584 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3585 emit_jump_insn (gen_blt (neglabel));
3587 /* The sign bit is not set. Convert as signed. */
3588 expand_float (target, from, 0);
3589 emit_jump_insn (gen_jump (label));
3590 emit_barrier ();
3592 /* The sign bit is set.
3593 Convert to a usable (positive signed) value by shifting right
3594 one bit, while remembering if a nonzero bit was shifted
3595 out; i.e., compute (from & 1) | (from >> 1). */
3597 emit_label (neglabel);
3598 temp = expand_binop (imode, and_optab, from, const1_rtx,
3599 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3600 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3601 NULL_RTX, 1);
3602 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3603 OPTAB_LIB_WIDEN);
3604 expand_float (target, temp, 0);
3606 /* Multiply by 2 to undo the shift above. */
3607 temp = expand_binop (fmode, add_optab, target, target,
3608 target, 0, OPTAB_LIB_WIDEN);
3609 if (temp != target)
3610 emit_move_insn (target, temp);
3612 do_pending_stack_adjust ();
3613 emit_label (label);
3614 goto done;
3618 /* If we are about to do some arithmetic to correct for an
3619 unsigned operand, do it in a pseudo-register. */
3621 if (GET_MODE (to) != fmode
3622 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3623 target = gen_reg_rtx (fmode);
3625 /* Convert as signed integer to floating. */
3626 expand_float (target, from, 0);
3628 /* If FROM is negative (and therefore TO is negative),
3629 correct its value by 2**bitwidth. */
3631 do_pending_stack_adjust ();
3632 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3633 emit_jump_insn (gen_bge (label));
3635 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3636 Rather than setting up a dconst_dot_5, let's hope SCO
3637 fixes the bug. */
3638 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3639 temp = expand_binop (fmode, add_optab, target,
3640 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3641 target, 0, OPTAB_LIB_WIDEN);
3642 if (temp != target)
3643 emit_move_insn (target, temp);
3645 do_pending_stack_adjust ();
3646 emit_label (label);
3647 goto done;
3649 #endif
3651 /* No hardware instruction available; call a library routine to convert from
3652 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3654 rtx libfcn;
3655 rtx insns;
3656 rtx value;
3658 to = protect_from_queue (to, 1);
3659 from = protect_from_queue (from, 0);
3661 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3662 from = convert_to_mode (SImode, from, unsignedp);
3664 if (flag_force_mem)
3665 from = force_not_mem (from);
3667 if (GET_MODE (to) == SFmode)
3669 if (GET_MODE (from) == SImode)
3670 libfcn = floatsisf_libfunc;
3671 else if (GET_MODE (from) == DImode)
3672 libfcn = floatdisf_libfunc;
3673 else if (GET_MODE (from) == TImode)
3674 libfcn = floattisf_libfunc;
3675 else
3676 abort ();
3678 else if (GET_MODE (to) == DFmode)
3680 if (GET_MODE (from) == SImode)
3681 libfcn = floatsidf_libfunc;
3682 else if (GET_MODE (from) == DImode)
3683 libfcn = floatdidf_libfunc;
3684 else if (GET_MODE (from) == TImode)
3685 libfcn = floattidf_libfunc;
3686 else
3687 abort ();
3689 else if (GET_MODE (to) == XFmode)
3691 if (GET_MODE (from) == SImode)
3692 libfcn = floatsixf_libfunc;
3693 else if (GET_MODE (from) == DImode)
3694 libfcn = floatdixf_libfunc;
3695 else if (GET_MODE (from) == TImode)
3696 libfcn = floattixf_libfunc;
3697 else
3698 abort ();
3700 else if (GET_MODE (to) == TFmode)
3702 if (GET_MODE (from) == SImode)
3703 libfcn = floatsitf_libfunc;
3704 else if (GET_MODE (from) == DImode)
3705 libfcn = floatditf_libfunc;
3706 else if (GET_MODE (from) == TImode)
3707 libfcn = floattitf_libfunc;
3708 else
3709 abort ();
3711 else
3712 abort ();
3714 start_sequence ();
3716 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3717 GET_MODE (to),
3718 1, from, GET_MODE (from));
3719 insns = get_insns ();
3720 end_sequence ();
3722 emit_libcall_block (insns, target, value,
3723 gen_rtx_FLOAT (GET_MODE (to), from));
3726 done:
3728 /* Copy result to requested destination
3729 if we have been computing in a temp location. */
3731 if (target != to)
3733 if (GET_MODE (target) == GET_MODE (to))
3734 emit_move_insn (to, target);
3735 else
3736 convert_move (to, target, 0);
3740 /* expand_fix: generate code to convert FROM to fixed point
3741 and store in TO. FROM must be floating point. */
3743 static rtx
3744 ftruncify (x)
3745 rtx x;
3747 rtx temp = gen_reg_rtx (GET_MODE (x));
3748 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3751 void
3752 expand_fix (to, from, unsignedp)
3753 register rtx to, from;
3754 int unsignedp;
3756 enum insn_code icode;
3757 register rtx target = to;
3758 enum machine_mode fmode, imode;
3759 int must_trunc = 0;
3760 rtx libfcn = 0;
3762 /* We first try to find a pair of modes, one real and one integer, at
3763 least as wide as FROM and TO, respectively, in which we can open-code
3764 this conversion. If the integer mode is wider than the mode of TO,
3765 we can do the conversion either signed or unsigned. */
3767 for (imode = GET_MODE (to); imode != VOIDmode;
3768 imode = GET_MODE_WIDER_MODE (imode))
3769 for (fmode = GET_MODE (from); fmode != VOIDmode;
3770 fmode = GET_MODE_WIDER_MODE (fmode))
3772 int doing_unsigned = unsignedp;
3774 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3775 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3776 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3778 if (icode != CODE_FOR_nothing)
3780 to = protect_from_queue (to, 1);
3781 from = protect_from_queue (from, 0);
3783 if (fmode != GET_MODE (from))
3784 from = convert_to_mode (fmode, from, 0);
3786 if (must_trunc)
3787 from = ftruncify (from);
3789 if (imode != GET_MODE (to))
3790 target = gen_reg_rtx (imode);
3792 emit_unop_insn (icode, target, from,
3793 doing_unsigned ? UNSIGNED_FIX : FIX);
3794 if (target != to)
3795 convert_move (to, target, unsignedp);
3796 return;
3800 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3801 /* For an unsigned conversion, there is one more way to do it.
3802 If we have a signed conversion, we generate code that compares
3803 the real value to the largest representable positive number. If if
3804 is smaller, the conversion is done normally. Otherwise, subtract
3805 one plus the highest signed number, convert, and add it back.
3807 We only need to check all real modes, since we know we didn't find
3808 anything with a wider integer mode. */
3810 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3811 for (fmode = GET_MODE (from); fmode != VOIDmode;
3812 fmode = GET_MODE_WIDER_MODE (fmode))
3813 /* Make sure we won't lose significant bits doing this. */
3814 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3815 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3816 &must_trunc))
3818 int bitsize;
3819 REAL_VALUE_TYPE offset;
3820 rtx limit, lab1, lab2, insn;
3822 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3823 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3824 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3825 lab1 = gen_label_rtx ();
3826 lab2 = gen_label_rtx ();
3828 emit_queue ();
3829 to = protect_from_queue (to, 1);
3830 from = protect_from_queue (from, 0);
3832 if (flag_force_mem)
3833 from = force_not_mem (from);
3835 if (fmode != GET_MODE (from))
3836 from = convert_to_mode (fmode, from, 0);
3838 /* See if we need to do the subtraction. */
3839 do_pending_stack_adjust ();
3840 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3841 emit_jump_insn (gen_bge (lab1));
3843 /* If not, do the signed "fix" and branch around fixup code. */
3844 expand_fix (to, from, 0);
3845 emit_jump_insn (gen_jump (lab2));
3846 emit_barrier ();
3848 /* Otherwise, subtract 2**(N-1), convert to signed number,
3849 then add 2**(N-1). Do the addition using XOR since this
3850 will often generate better code. */
3851 emit_label (lab1);
3852 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3853 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3854 expand_fix (to, target, 0);
3855 target = expand_binop (GET_MODE (to), xor_optab, to,
3856 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3857 to, 1, OPTAB_LIB_WIDEN);
3859 if (target != to)
3860 emit_move_insn (to, target);
3862 emit_label (lab2);
3864 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3865 != CODE_FOR_nothing)
3867 /* Make a place for a REG_NOTE and add it. */
3868 insn = emit_move_insn (to, to);
3869 REG_NOTES (insn)
3870 = gen_rtx_EXPR_LIST (REG_EQUAL,
3871 gen_rtx_fmt_e (UNSIGNED_FIX,
3872 GET_MODE (to),
3873 copy_rtx (from)),
3874 REG_NOTES (insn));
3876 return;
3878 #endif
3880 /* We can't do it with an insn, so use a library call. But first ensure
3881 that the mode of TO is at least as wide as SImode, since those are the
3882 only library calls we know about. */
3884 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3886 target = gen_reg_rtx (SImode);
3888 expand_fix (target, from, unsignedp);
3890 else if (GET_MODE (from) == SFmode)
3892 if (GET_MODE (to) == SImode)
3893 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3894 else if (GET_MODE (to) == DImode)
3895 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3896 else if (GET_MODE (to) == TImode)
3897 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3898 else
3899 abort ();
3901 else if (GET_MODE (from) == DFmode)
3903 if (GET_MODE (to) == SImode)
3904 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3905 else if (GET_MODE (to) == DImode)
3906 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3907 else if (GET_MODE (to) == TImode)
3908 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3909 else
3910 abort ();
3912 else if (GET_MODE (from) == XFmode)
3914 if (GET_MODE (to) == SImode)
3915 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3916 else if (GET_MODE (to) == DImode)
3917 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3918 else if (GET_MODE (to) == TImode)
3919 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3920 else
3921 abort ();
3923 else if (GET_MODE (from) == TFmode)
3925 if (GET_MODE (to) == SImode)
3926 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3927 else if (GET_MODE (to) == DImode)
3928 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3929 else if (GET_MODE (to) == TImode)
3930 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3931 else
3932 abort ();
3934 else
3935 abort ();
3937 if (libfcn)
3939 rtx insns;
3940 rtx value;
3942 to = protect_from_queue (to, 1);
3943 from = protect_from_queue (from, 0);
3945 if (flag_force_mem)
3946 from = force_not_mem (from);
3948 start_sequence ();
3950 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3952 1, from, GET_MODE (from));
3953 insns = get_insns ();
3954 end_sequence ();
3956 emit_libcall_block (insns, target, value,
3957 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
3958 GET_MODE (to), from));
3961 if (target != to)
3963 if (GET_MODE (to) == GET_MODE (target))
3964 emit_move_insn (to, target);
3965 else
3966 convert_move (to, target, 0);
3970 static optab
3971 init_optab (code)
3972 enum rtx_code code;
3974 int i;
3975 optab op = (optab) xmalloc (sizeof (struct optab));
3976 op->code = code;
3977 for (i = 0; i < NUM_MACHINE_MODES; i++)
3979 op->handlers[i].insn_code = CODE_FOR_nothing;
3980 op->handlers[i].libfunc = 0;
3983 if (code != UNKNOWN)
3984 code_to_optab[(int) code] = op;
3986 return op;
3989 /* Initialize the libfunc fields of an entire group of entries in some
3990 optab. Each entry is set equal to a string consisting of a leading
3991 pair of underscores followed by a generic operation name followed by
3992 a mode name (downshifted to lower case) followed by a single character
3993 representing the number of operands for the given operation (which is
3994 usually one of the characters '2', '3', or '4').
3996 OPTABLE is the table in which libfunc fields are to be initialized.
3997 FIRST_MODE is the first machine mode index in the given optab to
3998 initialize.
3999 LAST_MODE is the last machine mode index in the given optab to
4000 initialize.
4001 OPNAME is the generic (string) name of the operation.
4002 SUFFIX is the character which specifies the number of operands for
4003 the given generic operation.
4006 static void
4007 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4008 register optab optable;
4009 register int first_mode;
4010 register int last_mode;
4011 register char *opname;
4012 register int suffix;
4014 register int mode;
4015 register unsigned opname_len = strlen (opname);
4017 for (mode = first_mode; (int) mode <= (int) last_mode;
4018 mode = (enum machine_mode) ((int) mode + 1))
4020 register char *mname = mode_name[(int) mode];
4021 register unsigned mname_len = strlen (mname);
4022 register char *libfunc_name
4023 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4024 register char *p;
4025 register char *q;
4027 p = libfunc_name;
4028 *p++ = '_';
4029 *p++ = '_';
4030 for (q = opname; *q; )
4031 *p++ = *q++;
4032 for (q = mname; *q; q++)
4033 *p++ = tolower (*q);
4034 *p++ = suffix;
4035 *p++ = '\0';
4036 optable->handlers[(int) mode].libfunc
4037 = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4041 /* Initialize the libfunc fields of an entire group of entries in some
4042 optab which correspond to all integer mode operations. The parameters
4043 have the same meaning as similarly named ones for the `init_libfuncs'
4044 routine. (See above). */
4046 static void
4047 init_integral_libfuncs (optable, opname, suffix)
4048 register optab optable;
4049 register char *opname;
4050 register int suffix;
4052 init_libfuncs (optable, SImode, TImode, opname, suffix);
4055 /* Initialize the libfunc fields of an entire group of entries in some
4056 optab which correspond to all real mode operations. The parameters
4057 have the same meaning as similarly named ones for the `init_libfuncs'
4058 routine. (See above). */
4060 static void
4061 init_floating_libfuncs (optable, opname, suffix)
4062 register optab optable;
4063 register char *opname;
4064 register int suffix;
4066 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4070 /* Call this once to initialize the contents of the optabs
4071 appropriately for the current target machine. */
4073 void
4074 init_optabs ()
4076 int i;
4077 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4078 int j;
4079 #endif
4081 enum insn_code *p;
4083 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4085 for (p = fixtab[0][0];
4086 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4087 p++)
4088 *p = CODE_FOR_nothing;
4090 for (p = fixtrunctab[0][0];
4091 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4092 p++)
4093 *p = CODE_FOR_nothing;
4095 for (p = floattab[0][0];
4096 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4097 p++)
4098 *p = CODE_FOR_nothing;
4100 for (p = extendtab[0][0];
4101 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4102 p++)
4103 *p = CODE_FOR_nothing;
4105 for (i = 0; i < NUM_RTX_CODE; i++)
4106 setcc_gen_code[i] = CODE_FOR_nothing;
4108 #ifdef HAVE_conditional_move
4109 for (i = 0; i < NUM_MACHINE_MODES; i++)
4110 movcc_gen_code[i] = CODE_FOR_nothing;
4111 #endif
4113 add_optab = init_optab (PLUS);
4114 sub_optab = init_optab (MINUS);
4115 smul_optab = init_optab (MULT);
4116 smul_highpart_optab = init_optab (UNKNOWN);
4117 umul_highpart_optab = init_optab (UNKNOWN);
4118 smul_widen_optab = init_optab (UNKNOWN);
4119 umul_widen_optab = init_optab (UNKNOWN);
4120 sdiv_optab = init_optab (DIV);
4121 sdivmod_optab = init_optab (UNKNOWN);
4122 udiv_optab = init_optab (UDIV);
4123 udivmod_optab = init_optab (UNKNOWN);
4124 smod_optab = init_optab (MOD);
4125 umod_optab = init_optab (UMOD);
4126 flodiv_optab = init_optab (DIV);
4127 ftrunc_optab = init_optab (UNKNOWN);
4128 and_optab = init_optab (AND);
4129 ior_optab = init_optab (IOR);
4130 xor_optab = init_optab (XOR);
4131 ashl_optab = init_optab (ASHIFT);
4132 ashr_optab = init_optab (ASHIFTRT);
4133 lshr_optab = init_optab (LSHIFTRT);
4134 rotl_optab = init_optab (ROTATE);
4135 rotr_optab = init_optab (ROTATERT);
4136 smin_optab = init_optab (SMIN);
4137 smax_optab = init_optab (SMAX);
4138 umin_optab = init_optab (UMIN);
4139 umax_optab = init_optab (UMAX);
4140 mov_optab = init_optab (UNKNOWN);
4141 movstrict_optab = init_optab (UNKNOWN);
4142 cmp_optab = init_optab (UNKNOWN);
4143 ucmp_optab = init_optab (UNKNOWN);
4144 tst_optab = init_optab (UNKNOWN);
4145 neg_optab = init_optab (NEG);
4146 abs_optab = init_optab (ABS);
4147 one_cmpl_optab = init_optab (NOT);
4148 ffs_optab = init_optab (FFS);
4149 sqrt_optab = init_optab (SQRT);
4150 sin_optab = init_optab (UNKNOWN);
4151 cos_optab = init_optab (UNKNOWN);
4152 strlen_optab = init_optab (UNKNOWN);
4154 for (i = 0; i < NUM_MACHINE_MODES; i++)
4156 movstr_optab[i] = CODE_FOR_nothing;
4157 clrstr_optab[i] = CODE_FOR_nothing;
4159 #ifdef HAVE_SECONDARY_RELOADS
4160 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4161 #endif
4164 /* Fill in the optabs with the insns we support. */
4165 init_all_optabs ();
4167 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4168 /* This flag says the same insns that convert to a signed fixnum
4169 also convert validly to an unsigned one. */
4170 for (i = 0; i < NUM_MACHINE_MODES; i++)
4171 for (j = 0; j < NUM_MACHINE_MODES; j++)
4172 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4173 #endif
4175 #ifdef EXTRA_CC_MODES
4176 init_mov_optab ();
4177 #endif
4179 /* Initialize the optabs with the names of the library functions. */
4180 init_integral_libfuncs (add_optab, "add", '3');
4181 init_floating_libfuncs (add_optab, "add", '3');
4182 init_integral_libfuncs (sub_optab, "sub", '3');
4183 init_floating_libfuncs (sub_optab, "sub", '3');
4184 init_integral_libfuncs (smul_optab, "mul", '3');
4185 init_floating_libfuncs (smul_optab, "mul", '3');
4186 init_integral_libfuncs (sdiv_optab, "div", '3');
4187 init_integral_libfuncs (udiv_optab, "udiv", '3');
4188 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4189 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4190 init_integral_libfuncs (smod_optab, "mod", '3');
4191 init_integral_libfuncs (umod_optab, "umod", '3');
4192 init_floating_libfuncs (flodiv_optab, "div", '3');
4193 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4194 init_integral_libfuncs (and_optab, "and", '3');
4195 init_integral_libfuncs (ior_optab, "ior", '3');
4196 init_integral_libfuncs (xor_optab, "xor", '3');
4197 init_integral_libfuncs (ashl_optab, "ashl", '3');
4198 init_integral_libfuncs (ashr_optab, "ashr", '3');
4199 init_integral_libfuncs (lshr_optab, "lshr", '3');
4200 init_integral_libfuncs (smin_optab, "min", '3');
4201 init_floating_libfuncs (smin_optab, "min", '3');
4202 init_integral_libfuncs (smax_optab, "max", '3');
4203 init_floating_libfuncs (smax_optab, "max", '3');
4204 init_integral_libfuncs (umin_optab, "umin", '3');
4205 init_integral_libfuncs (umax_optab, "umax", '3');
4206 init_integral_libfuncs (neg_optab, "neg", '2');
4207 init_floating_libfuncs (neg_optab, "neg", '2');
4208 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4209 init_integral_libfuncs (ffs_optab, "ffs", '2');
4211 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4212 init_integral_libfuncs (cmp_optab, "cmp", '2');
4213 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4214 init_floating_libfuncs (cmp_optab, "cmp", '2');
4216 #ifdef MULSI3_LIBCALL
4217 smul_optab->handlers[(int) SImode].libfunc
4218 = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4219 #endif
4220 #ifdef MULDI3_LIBCALL
4221 smul_optab->handlers[(int) DImode].libfunc
4222 = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4223 #endif
4225 #ifdef DIVSI3_LIBCALL
4226 sdiv_optab->handlers[(int) SImode].libfunc
4227 = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4228 #endif
4229 #ifdef DIVDI3_LIBCALL
4230 sdiv_optab->handlers[(int) DImode].libfunc
4231 = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4232 #endif
4234 #ifdef UDIVSI3_LIBCALL
4235 udiv_optab->handlers[(int) SImode].libfunc
4236 = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4237 #endif
4238 #ifdef UDIVDI3_LIBCALL
4239 udiv_optab->handlers[(int) DImode].libfunc
4240 = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4241 #endif
4243 #ifdef MODSI3_LIBCALL
4244 smod_optab->handlers[(int) SImode].libfunc
4245 = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4246 #endif
4247 #ifdef MODDI3_LIBCALL
4248 smod_optab->handlers[(int) DImode].libfunc
4249 = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4250 #endif
4252 #ifdef UMODSI3_LIBCALL
4253 umod_optab->handlers[(int) SImode].libfunc
4254 = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4255 #endif
4256 #ifdef UMODDI3_LIBCALL
4257 umod_optab->handlers[(int) DImode].libfunc
4258 = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4259 #endif
4261 /* Use cabs for DC complex abs, since systems generally have cabs.
4262 Don't define any libcall for SCmode, so that cabs will be used. */
4263 abs_optab->handlers[(int) DCmode].libfunc
4264 = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4266 /* The ffs function operates on `int'. */
4267 #ifndef INT_TYPE_SIZE
4268 #define INT_TYPE_SIZE BITS_PER_WORD
4269 #endif
4270 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4271 = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4273 extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4274 extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4275 extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4276 extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4277 extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4279 truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4280 truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4281 trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4282 truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4283 trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4285 memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4286 bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4287 memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4288 bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4289 memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4290 bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4292 throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4293 sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4294 sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4295 terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4296 #ifndef DONT_USE_BUILTIN_SETJMP
4297 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4298 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4299 #else
4300 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4301 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4302 #endif
4304 eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4305 nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4306 gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4307 gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4308 lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4309 lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4311 eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4312 nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4313 gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4314 gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4315 ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4316 lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4318 eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4319 nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4320 gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4321 gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4322 ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4323 ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4325 eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4326 nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4327 gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4328 gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4329 ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4330 lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4332 eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4333 netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4334 gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4335 getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4336 lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4337 letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4339 floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4340 floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4341 floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4343 floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4344 floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4345 floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4347 floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4348 floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4349 floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4351 floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4352 floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4353 floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4355 fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4356 fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4357 fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4359 fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4360 fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4361 fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4363 fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4364 fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4365 fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4367 fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4368 fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4369 fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4371 fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4372 fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4373 fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4375 fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4376 fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4377 fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4379 fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4380 fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4381 fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4383 fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4384 fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4385 fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4387 /* For check-memory-usage. */
4388 chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_addr");
4389 chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_set_right");
4390 chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_copy_bitmap");
4391 chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_exec");
4392 chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (VOIDmode, "chkr_check_str");
4394 #ifdef HAVE_conditional_trap
4395 init_traps ();
4396 #endif
4398 #ifdef INIT_TARGET_OPTABS
4399 /* Allow the target to add more libcalls or rename some, etc. */
4400 INIT_TARGET_OPTABS;
4401 #endif
4404 #ifdef BROKEN_LDEXP
4406 /* SCO 3.2 apparently has a broken ldexp. */
4408 double
4409 ldexp(x,n)
4410 double x;
4411 int n;
4413 if (n > 0)
4414 while (n--)
4415 x *= 2;
4417 return x;
4419 #endif /* BROKEN_LDEXP */
4421 #ifdef HAVE_conditional_trap
4422 /* The insn generating function can not take an rtx_code argument.
4423 TRAP_RTX is used as an rtx argument. Its code is replaced with
4424 the code to be used in the trap insn and all other fields are
4425 ignored.
4427 ??? Will need to change to support garbage collection. */
4428 static rtx trap_rtx;
4430 static void
4431 init_traps ()
4433 if (HAVE_conditional_trap)
4434 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4436 #endif
4438 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4439 CODE. Return 0 on failure. */
4442 gen_cond_trap (code, op1, op2, tcode)
4443 enum rtx_code code;
4444 rtx op1, op2, tcode;
4446 enum machine_mode mode = GET_MODE (op1);
4448 if (mode == VOIDmode)
4449 return 0;
4451 #ifdef HAVE_conditional_trap
4452 if (HAVE_conditional_trap
4453 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4455 rtx insn;
4456 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4457 PUT_CODE (trap_rtx, code);
4458 insn = gen_conditional_trap (trap_rtx, tcode);
4459 if (insn)
4460 return insn;
4462 #endif
4464 return 0;