]> gcc.gnu.org Git - gcc.git/blame - gcc/optabs.c
reorg.c (fill_simple_delay_slots): Always try to fill empty delay slots with insns...
[gcc.git] / gcc / optabs.c
CommitLineData
77c9c6c2 1/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
34e56753 2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
77c9c6c2
RK
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "rtl.h"
23#include "tree.h"
24#include "flags.h"
25#include "insn-flags.h"
26#include "insn-codes.h"
27#include "expr.h"
28#include "insn-config.h"
29#include "recog.h"
2d9f831e 30#include <ctype.h>
77c9c6c2
RK
31
32/* Each optab contains info on how this target machine
33 can perform a particular operation
34 for all sizes and kinds of operands.
35
36 The operation to be performed is often specified
37 by passing one of these optabs as an argument.
38
39 See expr.h for documentation of these optabs. */
40
41optab add_optab;
42optab sub_optab;
43optab smul_optab;
44optab smul_widen_optab;
45optab umul_widen_optab;
46optab sdiv_optab;
47optab sdivmod_optab;
48optab udiv_optab;
49optab udivmod_optab;
50optab smod_optab;
51optab umod_optab;
52optab flodiv_optab;
53optab ftrunc_optab;
54optab and_optab;
55optab ior_optab;
56optab xor_optab;
57optab ashl_optab;
58optab lshr_optab;
59optab lshl_optab;
60optab ashr_optab;
61optab rotl_optab;
62optab rotr_optab;
63optab smin_optab;
64optab smax_optab;
65optab umin_optab;
66optab umax_optab;
67
68optab mov_optab;
69optab movstrict_optab;
70
71optab neg_optab;
72optab abs_optab;
73optab one_cmpl_optab;
74optab ffs_optab;
d45cf215 75optab sqrt_optab;
77c9c6c2
RK
76
77optab cmp_optab;
78optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
79optab tst_optab;
80
19c3fc24
RS
81optab strlen_optab;
82
77c9c6c2
RK
83/* SYMBOL_REF rtx's for the library functions that are called
84 implicitly and not via optabs. */
85
86rtx extendsfdf2_libfunc;
b092b471
JW
87rtx extendsfxf2_libfunc;
88rtx extendsftf2_libfunc;
89rtx extenddfxf2_libfunc;
90rtx extenddftf2_libfunc;
91
77c9c6c2 92rtx truncdfsf2_libfunc;
b092b471
JW
93rtx truncxfsf2_libfunc;
94rtx trunctfsf2_libfunc;
95rtx truncxfdf2_libfunc;
96rtx trunctfdf2_libfunc;
97
77c9c6c2
RK
98rtx memcpy_libfunc;
99rtx bcopy_libfunc;
100rtx memcmp_libfunc;
101rtx bcmp_libfunc;
102rtx memset_libfunc;
103rtx bzero_libfunc;
b092b471 104
77c9c6c2
RK
105rtx eqsf2_libfunc;
106rtx nesf2_libfunc;
107rtx gtsf2_libfunc;
108rtx gesf2_libfunc;
109rtx ltsf2_libfunc;
110rtx lesf2_libfunc;
b092b471 111
77c9c6c2
RK
112rtx eqdf2_libfunc;
113rtx nedf2_libfunc;
114rtx gtdf2_libfunc;
115rtx gedf2_libfunc;
116rtx ltdf2_libfunc;
117rtx ledf2_libfunc;
b092b471
JW
118
119rtx eqxf2_libfunc;
120rtx nexf2_libfunc;
121rtx gtxf2_libfunc;
122rtx gexf2_libfunc;
123rtx ltxf2_libfunc;
124rtx lexf2_libfunc;
125
126rtx eqtf2_libfunc;
127rtx netf2_libfunc;
128rtx gttf2_libfunc;
129rtx getf2_libfunc;
130rtx lttf2_libfunc;
131rtx letf2_libfunc;
132
6bce1b78 133rtx floatsisf_libfunc;
b092b471
JW
134rtx floatdisf_libfunc;
135rtx floattisf_libfunc;
136
6bce1b78 137rtx floatsidf_libfunc;
b092b471
JW
138rtx floatdidf_libfunc;
139rtx floattidf_libfunc;
140
141rtx floatsixf_libfunc;
142rtx floatdixf_libfunc;
143rtx floattixf_libfunc;
144
145rtx floatsitf_libfunc;
146rtx floatditf_libfunc;
147rtx floattitf_libfunc;
148
6bce1b78
RK
149rtx fixsfsi_libfunc;
150rtx fixsfdi_libfunc;
b092b471
JW
151rtx fixsfti_libfunc;
152
6bce1b78
RK
153rtx fixdfsi_libfunc;
154rtx fixdfdi_libfunc;
b092b471
JW
155rtx fixdfti_libfunc;
156
157rtx fixxfsi_libfunc;
158rtx fixxfdi_libfunc;
159rtx fixxfti_libfunc;
160
161rtx fixtfsi_libfunc;
162rtx fixtfdi_libfunc;
163rtx fixtfti_libfunc;
164
6bce1b78
RK
165rtx fixunssfsi_libfunc;
166rtx fixunssfdi_libfunc;
b092b471
JW
167rtx fixunssfti_libfunc;
168
6bce1b78
RK
169rtx fixunsdfsi_libfunc;
170rtx fixunsdfdi_libfunc;
b092b471
JW
171rtx fixunsdfti_libfunc;
172
173rtx fixunsxfsi_libfunc;
174rtx fixunsxfdi_libfunc;
175rtx fixunsxfti_libfunc;
176
177rtx fixunstfsi_libfunc;
178rtx fixunstfdi_libfunc;
179rtx fixunstfti_libfunc;
77c9c6c2
RK
180
181/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
182 gives the gen_function to make a branch to test that condition. */
183
184rtxfun bcc_gen_fctn[NUM_RTX_CODE];
185
186/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
187 gives the insn code to make a store-condition insn
188 to test that condition. */
189
190enum insn_code setcc_gen_code[NUM_RTX_CODE];
191
192static void emit_float_lib_cmp ();
193\f
194/* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
195 the result of operation CODE applied to OP0 (and OP1 if it is a binary
196 operation).
197
198 If the last insn does not set TARGET, don't do anything, but return 1.
199
200 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
201 don't add the REG_EQUAL note but return 0. Our caller can then try
202 again, ensuring that TARGET is not one of the operands. */
203
204static int
205add_equal_note (seq, target, code, op0, op1)
206 rtx seq;
207 rtx target;
208 enum rtx_code code;
209 rtx op0, op1;
210{
211 rtx set;
212 int i;
213 rtx note;
214
215 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
216 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
217 || GET_CODE (seq) != SEQUENCE
218 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
219 || GET_CODE (target) == ZERO_EXTRACT
220 || (! rtx_equal_p (SET_DEST (set), target)
221 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
222 SUBREG. */
223 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
224 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
225 target))))
226 return 1;
227
228 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
229 besides the last insn. */
230 if (reg_overlap_mentioned_p (target, op0)
231 || (op1 && reg_overlap_mentioned_p (target, op1)))
232 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
233 if (reg_set_p (target, XVECEXP (seq, 0, i)))
234 return 0;
235
236 if (GET_RTX_CLASS (code) == '1')
237 note = gen_rtx (code, GET_MODE (target), op0);
238 else
239 note = gen_rtx (code, GET_MODE (target), op0, op1);
240
241 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
242 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
243 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
244
245 return 1;
246}
247\f
248/* Generate code to perform an operation specified by BINOPTAB
249 on operands OP0 and OP1, with result having machine-mode MODE.
250
251 UNSIGNEDP is for the case where we have to widen the operands
252 to perform the operation. It says to use zero-extension.
253
254 If TARGET is nonzero, the value
255 is generated there, if it is convenient to do so.
256 In all cases an rtx is returned for the locus of the value;
257 this may or may not be TARGET. */
258
259rtx
260expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
261 enum machine_mode mode;
262 optab binoptab;
263 rtx op0, op1;
264 rtx target;
265 int unsignedp;
266 enum optab_methods methods;
267{
268 enum mode_class class;
269 enum machine_mode wider_mode;
77c9c6c2
RK
270 register rtx temp;
271 int commutative_op = 0;
272 int shift_op = (binoptab->code == ASHIFT
273 || binoptab->code == ASHIFTRT
274 || binoptab->code == LSHIFT
275 || binoptab->code == LSHIFTRT
276 || binoptab->code == ROTATE
277 || binoptab->code == ROTATERT);
278 rtx last;
279
280 class = GET_MODE_CLASS (mode);
281
282 op0 = protect_from_queue (op0, 0);
283 op1 = protect_from_queue (op1, 0);
284 if (target)
285 target = protect_from_queue (target, 1);
286
287 if (flag_force_mem)
288 {
289 op0 = force_not_mem (op0);
290 op1 = force_not_mem (op1);
291 }
292
293 /* If we are inside an appropriately-short loop and one operand is an
294 expensive constant, force it into a register. */
aeedc93f
RS
295 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
296 && rtx_cost (op0, binoptab->code) > 2)
77c9c6c2
RK
297 op0 = force_reg (mode, op0);
298
aeedc93f
RS
299 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
300 && rtx_cost (op1, binoptab->code) > 2)
34e56753 301 op1 = force_reg (shift_op ? word_mode : mode, op1);
77c9c6c2
RK
302
303#if 0 /* Turned off because it seems to be a kludgy method. */
304 /* If subtracting integer from pointer, and the pointer has a special mode,
305 then change it to an add. We use the add insn of Pmode for combining
306 integers with pointers, and the sub insn to subtract two pointers. */
307
308 if (binoptab == sub_optab
309 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
310 {
311 op1 = negate_rtx (GET_MODE(op1), op1);
312 binoptab = add_optab;
313 }
314#endif /* 0 */
315
316 /* Record where to delete back to if we backtrack. */
317 last = get_last_insn ();
318
319 /* If operation is commutative,
320 try to make the first operand a register.
321 Even better, try to make it the same as the target.
322 Also try to make the last operand a constant. */
323 if (GET_RTX_CLASS (binoptab->code) == 'c'
324 || binoptab == smul_widen_optab
325 || binoptab == umul_widen_optab)
326 {
327 commutative_op = 1;
328
329 if (((target == 0 || GET_CODE (target) == REG)
330 ? ((GET_CODE (op1) == REG
331 && GET_CODE (op0) != REG)
332 || target == op1)
333 : rtx_equal_p (op1, target))
334 || GET_CODE (op0) == CONST_INT)
335 {
336 temp = op1;
337 op1 = op0;
338 op0 = temp;
339 }
340 }
341
342 /* If we can do it with a three-operand insn, do so. */
343
344 if (methods != OPTAB_MUST_WIDEN
345 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
346 {
347 int icode = (int) binoptab->handlers[(int) mode].insn_code;
348 enum machine_mode mode0 = insn_operand_mode[icode][1];
349 enum machine_mode mode1 = insn_operand_mode[icode][2];
350 rtx pat;
351 rtx xop0 = op0, xop1 = op1;
352
353 if (target)
354 temp = target;
355 else
356 temp = gen_reg_rtx (mode);
357
358 /* If it is a commutative operator and the modes would match
359 if we would swap the operands, we can save the conversions. */
360 if (commutative_op)
361 {
362 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
363 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
364 {
365 register rtx tmp;
366
367 tmp = op0; op0 = op1; op1 = tmp;
368 tmp = xop0; xop0 = xop1; xop1 = tmp;
369 }
370 }
371
372 /* In case the insn wants input operands in modes different from
373 the result, convert the operands. */
374
375 if (GET_MODE (op0) != VOIDmode
376 && GET_MODE (op0) != mode0)
377 xop0 = convert_to_mode (mode0, xop0, unsignedp);
378
379 if (GET_MODE (xop1) != VOIDmode
380 && GET_MODE (xop1) != mode1)
381 xop1 = convert_to_mode (mode1, xop1, unsignedp);
382
383 /* Now, if insn's predicates don't allow our operands, put them into
384 pseudo regs. */
385
386 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
387 xop0 = copy_to_mode_reg (mode0, xop0);
388
389 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
390 xop1 = copy_to_mode_reg (mode1, xop1);
391
392 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
393 temp = gen_reg_rtx (mode);
394
395 pat = GEN_FCN (icode) (temp, xop0, xop1);
396 if (pat)
397 {
398 /* If PAT is a multi-insn sequence, try to add an appropriate
399 REG_EQUAL note to it. If we can't because TEMP conflicts with an
400 operand, call ourselves again, this time without a target. */
401 if (GET_CODE (pat) == SEQUENCE
402 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
403 {
404 delete_insns_since (last);
b1ec3c92
CH
405 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
406 unsignedp, methods);
77c9c6c2
RK
407 }
408
409 emit_insn (pat);
410 return temp;
411 }
412 else
413 delete_insns_since (last);
414 }
415
9a856ec7
RK
416 /* Look for a wider mode of the same class for which we think we
417 can open-code the operation. */
418
419 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
420 && mode != OPTAB_DIRECT && mode != OPTAB_LIB)
421 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
422 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
423 {
424 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
425 {
426 rtx xop0 = op0, xop1 = op1;
427 int no_extend = 0;
428
429 /* For certain integer operations, we need not actually extend
430 the narrow operands, as long as we will truncate
431 the results to the same narrowness. */
432
433 if ((binoptab == ior_optab || binoptab == and_optab
434 || binoptab == xor_optab
435 || binoptab == add_optab || binoptab == sub_optab
436 || binoptab == smul_optab
437 || binoptab == ashl_optab || binoptab == lshl_optab)
438 && class == MODE_INT)
439 no_extend = 1;
440
441 /* If an operand is a constant integer, we might as well
442 convert it since that is more efficient than using a SUBREG,
443 unlike the case for other operands. */
444
445 if (no_extend && GET_MODE (xop0) != VOIDmode)
446 xop0 = gen_rtx (SUBREG, wider_mode,
447 force_reg (GET_MODE (xop0), xop0), 0);
448 else
449 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
450
451 if (no_extend && GET_MODE (xop1) != VOIDmode)
452 xop1 = gen_rtx (SUBREG, wider_mode,
453 force_reg (GET_MODE (xop1), xop1), 0);
454 else
455 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
456
b1ec3c92 457 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
9a856ec7
RK
458 unsignedp, OPTAB_DIRECT);
459 if (temp)
460 {
461 if (class != MODE_INT)
462 {
463 if (target == 0)
464 target = gen_reg_rtx (mode);
465 convert_move (target, temp, 0);
466 return target;
467 }
468 else
469 return gen_lowpart (mode, temp);
470 }
471 else
472 delete_insns_since (last);
473 }
474 }
475
77c9c6c2
RK
476 /* These can be done a word at a time. */
477 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
478 && class == MODE_INT
479 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
34e56753 480 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2
RK
481 {
482 int i;
483 rtx insns;
484 rtx equiv_value;
485
486 /* If TARGET is the same as one of the operands, the REG_EQUAL note
487 won't be accurate, so use a new target. */
488 if (target == 0 || target == op0 || target == op1)
489 target = gen_reg_rtx (mode);
490
491 start_sequence ();
492
493 /* Do the actual arithmetic. */
494 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
495 {
496 rtx target_piece = operand_subword (target, i, 1, mode);
34e56753 497 rtx x = expand_binop (word_mode, binoptab,
77c9c6c2
RK
498 operand_subword_force (op0, i, mode),
499 operand_subword_force (op1, i, mode),
500 target_piece, unsignedp, methods);
501 if (target_piece != x)
502 emit_move_insn (target_piece, x);
503 }
504
505 insns = get_insns ();
506 end_sequence ();
507
508 if (binoptab->code != UNKNOWN)
509 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
510 else
511 equiv_value = 0;
512
513 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
514 return target;
515 }
516
517 /* These can be done a word at a time by propagating carries. */
518 if ((binoptab == add_optab || binoptab == sub_optab)
519 && class == MODE_INT
520 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
34e56753 521 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2
RK
522 {
523 int i;
34e56753 524 rtx carry_tmp = gen_reg_rtx (word_mode);
77c9c6c2
RK
525 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
526 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
527 rtx carry_in, carry_out;
528
529 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
530 value is one of those, use it. Otherwise, use 1 since it is the
531 one easiest to get. */
532#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
533 int normalizep = STORE_FLAG_VALUE;
534#else
535 int normalizep = 1;
536#endif
537
538 /* Prepare the operands. */
539 op0 = force_reg (mode, op0);
540 op1 = force_reg (mode, op1);
541
542 if (target == 0 || GET_CODE (target) != REG
543 || target == op0 || target == op1)
544 target = gen_reg_rtx (mode);
545
546 /* Do the actual arithmetic. */
547 for (i = 0; i < nwords; i++)
548 {
549 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
550 rtx target_piece = operand_subword (target, index, 1, mode);
551 rtx op0_piece = operand_subword_force (op0, index, mode);
552 rtx op1_piece = operand_subword_force (op1, index, mode);
553 rtx x;
554
555 /* Main add/subtract of the input operands. */
34e56753 556 x = expand_binop (word_mode, binoptab,
77c9c6c2
RK
557 op0_piece, op1_piece,
558 target_piece, unsignedp, methods);
559 if (x == 0)
560 break;
561
562 if (i + 1 < nwords)
563 {
564 /* Store carry from main add/subtract. */
34e56753 565 carry_out = gen_reg_rtx (word_mode);
77c9c6c2
RK
566 carry_out = emit_store_flag (carry_out,
567 binoptab == add_optab ? LTU : GTU,
568 x, op0_piece,
34e56753 569 word_mode, 1, normalizep);
77c9c6c2
RK
570 if (!carry_out)
571 break;
572 }
573
574 if (i > 0)
575 {
576 /* Add/subtract previous carry to main result. */
34e56753 577 x = expand_binop (word_mode,
77c9c6c2
RK
578 normalizep == 1 ? binoptab : otheroptab,
579 x, carry_in,
580 target_piece, 1, methods);
581 if (target_piece != x)
582 emit_move_insn (target_piece, x);
583
584 if (i + 1 < nwords)
585 {
586 /* THIS CODE HAS NOT BEEN TESTED. */
587 /* Get out carry from adding/subtracting carry in. */
588 carry_tmp = emit_store_flag (carry_tmp,
589 binoptab == add_optab
590 ? LTU : GTU,
591 x, carry_in,
34e56753 592 word_mode, 1, normalizep);
77c9c6c2 593 /* Logical-ior the two poss. carry together. */
34e56753 594 carry_out = expand_binop (word_mode, ior_optab,
77c9c6c2
RK
595 carry_out, carry_tmp,
596 carry_out, 0, methods);
597 if (!carry_out)
598 break;
599 }
600 }
601
602 carry_in = carry_out;
603 }
604
605 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
606 {
607 rtx temp;
608
609 temp = emit_move_insn (target, target);
610 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
611 gen_rtx (binoptab->code, mode, op0, op1),
612 REG_NOTES (temp));
613 return target;
614 }
615 else
616 delete_insns_since (last);
617 }
618
619 /* If we want to multiply two two-word values and have normal and widening
620 multiplies of single-word values, we can do this with three smaller
621 multiplications. Note that we do not make a REG_NO_CONFLICT block here
622 because we are not operating on one word at a time.
623
624 The multiplication proceeds as follows:
34e56753
RS
625 _______________________
626 [__op0_high_|__op0_low__]
627 _______________________
628 * [__op1_high_|__op1_low__]
629 _______________________________________________
630 _______________________
631 (1) [__op0_low__*__op1_low__]
632 _______________________
633 (2a) [__op0_low__*__op1_high_]
634 _______________________
635 (2b) [__op0_high_*__op1_low__]
636 _______________________
637 (3) [__op0_high_*__op1_high_]
77c9c6c2
RK
638
639
640 This gives a 4-word result. Since we are only interested in the
641 lower 2 words, partial result (3) and the upper words of (2a) and
642 (2b) don't need to be calculated. Hence (2a) and (2b) can be
643 calculated using non-widening multiplication.
644
645 (1), however, needs to be calculated with an unsigned widening
646 multiplication. If this operation is not directly supported we
647 try using a signed widening multiplication and adjust the result.
648 This adjustment works as follows:
649
650 If both operands are positive then no adjustment is needed.
651
652 If the operands have different signs, for example op0_low < 0 and
653 op1_low >= 0, the instruction treats the most significant bit of
654 op0_low as a sign bit instead of a bit with significance
655 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
656 with 2**BITS_PER_WORD - op0_low, and two's complements the
657 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
658 the result.
659
660 Similarly, if both operands are negative, we need to add
661 (op0_low + op1_low) * 2**BITS_PER_WORD.
662
663 We use a trick to adjust quickly. We logically shift op0_low right
664 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
665 op0_high (op1_high) before it is used to calculate 2b (2a). If no
666 logical shift exists, we do an arithmetic right shift and subtract
667 the 0 or -1. */
668
669 if (binoptab == smul_optab
670 && class == MODE_INT
671 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
34e56753
RS
672 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
673 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
77c9c6c2
RK
674 && ((umul_widen_optab->handlers[(int) mode].insn_code
675 != CODE_FOR_nothing)
676 || (smul_widen_optab->handlers[(int) mode].insn_code
677 != CODE_FOR_nothing)))
678 {
679 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
680 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
681 rtx op0_high = operand_subword_force (op0, high, mode);
682 rtx op0_low = operand_subword_force (op0, low, mode);
683 rtx op1_high = operand_subword_force (op1, high, mode);
684 rtx op1_low = operand_subword_force (op1, low, mode);
685 rtx product = 0;
686 rtx op0_xhigh;
687 rtx op1_xhigh;
688
689 /* If the target is the same as one of the inputs, don't use it. This
690 prevents problems with the REG_EQUAL note. */
691 if (target == op0 || target == op1)
692 target = 0;
693
694 /* Multiply the two lower words to get a double-word product.
695 If unsigned widening multiplication is available, use that;
696 otherwise use the signed form and compensate. */
697
698 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
699 {
700 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
701 target, 1, OPTAB_DIRECT);
702
703 /* If we didn't succeed, delete everything we did so far. */
704 if (product == 0)
705 delete_insns_since (last);
706 else
707 op0_xhigh = op0_high, op1_xhigh = op1_high;
708 }
709
710 if (product == 0
711 && smul_widen_optab->handlers[(int) mode].insn_code
712 != CODE_FOR_nothing)
713 {
b1ec3c92 714 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
77c9c6c2
RK
715 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
716 target, 1, OPTAB_DIRECT);
34e56753 717 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
b1ec3c92 718 NULL_RTX, 1, OPTAB_DIRECT);
77c9c6c2 719 if (op0_xhigh)
34e56753
RS
720 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
721 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
77c9c6c2
RK
722 else
723 {
34e56753 724 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
b1ec3c92 725 NULL_RTX, 0, OPTAB_DIRECT);
77c9c6c2 726 if (op0_xhigh)
34e56753 727 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
77c9c6c2
RK
728 op0_xhigh, op0_xhigh, 0,
729 OPTAB_DIRECT);
730 }
731
34e56753 732 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
b1ec3c92 733 NULL_RTX, 1, OPTAB_DIRECT);
77c9c6c2 734 if (op1_xhigh)
34e56753
RS
735 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
736 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
77c9c6c2
RK
737 else
738 {
34e56753 739 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
b1ec3c92 740 NULL_RTX, 0, OPTAB_DIRECT);
77c9c6c2 741 if (op1_xhigh)
34e56753 742 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
77c9c6c2
RK
743 op1_xhigh, op1_xhigh, 0,
744 OPTAB_DIRECT);
745 }
746 }
747
748 /* If we have been able to directly compute the product of the
749 low-order words of the operands and perform any required adjustments
750 of the operands, we proceed by trying two more multiplications
751 and then computing the appropriate sum.
752
753 We have checked above that the required addition is provided.
754 Full-word addition will normally always succeed, especially if
755 it is provided at all, so we don't worry about its failure. The
756 multiplication may well fail, however, so we do handle that. */
757
758 if (product && op0_xhigh && op1_xhigh)
759 {
760 rtx product_piece;
761 rtx product_high = operand_subword (product, high, 1, mode);
b1ec3c92
CH
762 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
763 NULL_RTX, 0, OPTAB_DIRECT);
77c9c6c2
RK
764
765 if (temp)
766 {
34e56753 767 product_piece = expand_binop (word_mode, add_optab, temp,
77c9c6c2
RK
768 product_high, product_high,
769 0, OPTAB_LIB_WIDEN);
770 if (product_piece != product_high)
771 emit_move_insn (product_high, product_piece);
772
b1ec3c92
CH
773 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
774 NULL_RTX, 0, OPTAB_DIRECT);
77c9c6c2 775
34e56753 776 product_piece = expand_binop (word_mode, add_optab, temp,
77c9c6c2
RK
777 product_high, product_high,
778 0, OPTAB_LIB_WIDEN);
779 if (product_piece != product_high)
780 emit_move_insn (product_high, product_piece);
781
782 temp = emit_move_insn (product, product);
783 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
784 gen_rtx (MULT, mode, op0, op1),
785 REG_NOTES (temp));
786
787 return product;
788 }
789 }
790
791 /* If we get here, we couldn't do it for some reason even though we
792 originally thought we could. Delete anything we've emitted in
793 trying to do it. */
794
795 delete_insns_since (last);
796 }
797
798 /* It can't be open-coded in this mode.
799 Use a library call if one is available and caller says that's ok. */
800
801 if (binoptab->handlers[(int) mode].libfunc
802 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
803 {
804 rtx insns;
805 rtx funexp = binoptab->handlers[(int) mode].libfunc;
806
807 start_sequence ();
808
809 /* Pass 1 for NO_QUEUE so we don't lose any increments
810 if the libcall is cse'd or moved. */
811 emit_library_call (binoptab->handlers[(int) mode].libfunc,
812 1, mode, 2, op0, mode, op1,
34e56753 813 (shift_op ? word_mode : mode));
77c9c6c2
RK
814
815 insns = get_insns ();
816 end_sequence ();
817
818 target = gen_reg_rtx (mode);
819 emit_libcall_block (insns, target, hard_libcall_value (mode),
820 gen_rtx (binoptab->code, mode, op0, op1));
821
822 return target;
823 }
824
825 delete_insns_since (last);
826
827 /* It can't be done in this mode. Can we do it in a wider mode? */
828
829 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
830 || methods == OPTAB_MUST_WIDEN))
831 return 0; /* Caller says, don't even try. */
832
833 /* Compute the value of METHODS to pass to recursive calls.
834 Don't allow widening to be tried recursively. */
835
836 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
837
34e56753
RS
838 /* Look for a wider mode of the same class for which it appears we can do
839 the operation. */
77c9c6c2
RK
840
841 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
842 {
34e56753 843 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
844 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
845 {
846 if ((binoptab->handlers[(int) wider_mode].insn_code
847 != CODE_FOR_nothing)
848 || (methods == OPTAB_LIB
849 && binoptab->handlers[(int) wider_mode].libfunc))
850 {
851 rtx xop0 = op0, xop1 = op1;
852 int no_extend = 0;
853
34e56753 854 /* For certain integer operations, we need not actually extend
77c9c6c2
RK
855 the narrow operands, as long as we will truncate
856 the results to the same narrowness. */
857
34e56753
RS
858 if ((binoptab == ior_optab || binoptab == and_optab
859 || binoptab == xor_optab
860 || binoptab == add_optab || binoptab == sub_optab
861 || binoptab == smul_optab
862 || binoptab == ashl_optab || binoptab == lshl_optab)
863 && class == MODE_INT)
77c9c6c2
RK
864 no_extend = 1;
865
34e56753
RS
866 /* If an operand is a constant integer, we might as well
867 convert it since that is more efficient than using a SUBREG,
868 unlike the case for other operands. */
869
870 if (no_extend && GET_MODE (xop0) != VOIDmode)
871 xop0 = gen_rtx (SUBREG, wider_mode,
872 force_reg (GET_MODE (xop0), xop0), 0);
873 else
874 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
875
876 if (no_extend && GET_MODE (xop1) != VOIDmode)
877 xop1 = gen_rtx (SUBREG, wider_mode,
878 force_reg (GET_MODE (xop1), xop1), 0);
879 else
880 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
77c9c6c2 881
b1ec3c92 882 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
77c9c6c2
RK
883 unsignedp, methods);
884 if (temp)
885 {
34e56753 886 if (class != MODE_INT)
77c9c6c2
RK
887 {
888 if (target == 0)
889 target = gen_reg_rtx (mode);
890 convert_move (target, temp, 0);
891 return target;
892 }
893 else
894 return gen_lowpart (mode, temp);
895 }
896 else
897 delete_insns_since (last);
898 }
899 }
900 }
901
902 return 0;
903}
904\f
905/* Expand a binary operator which has both signed and unsigned forms.
906 UOPTAB is the optab for unsigned operations, and SOPTAB is for
907 signed operations.
908
909 If we widen unsigned operands, we may use a signed wider operation instead
910 of an unsigned wider operation, since the result would be the same. */
911
912rtx
913sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
914 enum machine_mode mode;
915 optab uoptab, soptab;
916 rtx op0, op1, target;
917 int unsignedp;
918 enum optab_methods methods;
919{
920 register rtx temp;
921 optab direct_optab = unsignedp ? uoptab : soptab;
922 struct optab wide_soptab;
923
924 /* Do it without widening, if possible. */
925 temp = expand_binop (mode, direct_optab, op0, op1, target,
926 unsignedp, OPTAB_DIRECT);
927 if (temp || methods == OPTAB_DIRECT)
928 return temp;
929
930 /* Try widening to a signed int. Make a fake signed optab that
931 hides any signed insn for direct use. */
932 wide_soptab = *soptab;
933 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
934 wide_soptab.handlers[(int) mode].libfunc = 0;
935
936 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
937 unsignedp, OPTAB_WIDEN);
938
939 /* For unsigned operands, try widening to an unsigned int. */
940 if (temp == 0 && unsignedp)
941 temp = expand_binop (mode, uoptab, op0, op1, target,
942 unsignedp, OPTAB_WIDEN);
943 if (temp || methods == OPTAB_WIDEN)
944 return temp;
945
946 /* Use the right width lib call if that exists. */
947 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
948 if (temp || methods == OPTAB_LIB)
949 return temp;
950
951 /* Must widen and use a lib call, use either signed or unsigned. */
952 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
953 unsignedp, methods);
954 if (temp != 0)
955 return temp;
956 if (unsignedp)
957 return expand_binop (mode, uoptab, op0, op1, target,
958 unsignedp, methods);
959 return 0;
960}
961\f
962/* Generate code to perform an operation specified by BINOPTAB
963 on operands OP0 and OP1, with two results to TARG1 and TARG2.
964 We assume that the order of the operands for the instruction
965 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
966 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
967
968 Either TARG0 or TARG1 may be zero, but what that means is that
969 that result is not actually wanted. We will generate it into
970 a dummy pseudo-reg and discard it. They may not both be zero.
971
972 Returns 1 if this operation can be performed; 0 if not. */
973
974int
975expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
976 optab binoptab;
977 rtx op0, op1;
978 rtx targ0, targ1;
979 int unsignedp;
980{
981 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
982 enum mode_class class;
983 enum machine_mode wider_mode;
984 rtx last;
985
986 class = GET_MODE_CLASS (mode);
987
988 op0 = protect_from_queue (op0, 0);
989 op1 = protect_from_queue (op1, 0);
990
991 if (flag_force_mem)
992 {
993 op0 = force_not_mem (op0);
994 op1 = force_not_mem (op1);
995 }
996
997 /* If we are inside an appropriately-short loop and one operand is an
998 expensive constant, force it into a register. */
aeedc93f
RS
999 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1000 && rtx_cost (op0, binoptab->code) > 2)
77c9c6c2
RK
1001 op0 = force_reg (mode, op0);
1002
aeedc93f
RS
1003 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1004 && rtx_cost (op1, binoptab->code) > 2)
77c9c6c2
RK
1005 op1 = force_reg (mode, op1);
1006
1007 if (targ0)
1008 targ0 = protect_from_queue (targ0, 1);
1009 else
1010 targ0 = gen_reg_rtx (mode);
1011 if (targ1)
1012 targ1 = protect_from_queue (targ1, 1);
1013 else
1014 targ1 = gen_reg_rtx (mode);
1015
1016 /* Record where to go back to if we fail. */
1017 last = get_last_insn ();
1018
1019 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1020 {
1021 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1022 enum machine_mode mode0 = insn_operand_mode[icode][1];
1023 enum machine_mode mode1 = insn_operand_mode[icode][2];
1024 rtx pat;
1025 rtx xop0 = op0, xop1 = op1;
1026
1027 /* In case this insn wants input operands in modes different from the
1028 result, convert the operands. */
1029 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1030 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1031
1032 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1033 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1034
1035 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1036 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1037 xop0 = copy_to_mode_reg (mode0, xop0);
1038
1039 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1040 xop1 = copy_to_mode_reg (mode1, xop1);
1041
1042 /* We could handle this, but we should always be called with a pseudo
1043 for our targets and all insns should take them as outputs. */
1044 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1045 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1046 abort ();
1047
1048 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1049 if (pat)
1050 {
1051 emit_insn (pat);
1052 return 1;
1053 }
1054 else
1055 delete_insns_since (last);
1056 }
1057
1058 /* It can't be done in this mode. Can we do it in a wider mode? */
1059
1060 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1061 {
34e56753 1062 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1063 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1064 {
1065 if (binoptab->handlers[(int) wider_mode].insn_code
1066 != CODE_FOR_nothing)
1067 {
1068 register rtx t0 = gen_reg_rtx (wider_mode);
1069 register rtx t1 = gen_reg_rtx (wider_mode);
1070
1071 if (expand_twoval_binop (binoptab,
1072 convert_to_mode (wider_mode, op0,
1073 unsignedp),
1074 convert_to_mode (wider_mode, op1,
1075 unsignedp),
1076 t0, t1, unsignedp))
1077 {
1078 convert_move (targ0, t0, unsignedp);
1079 convert_move (targ1, t1, unsignedp);
1080 return 1;
1081 }
1082 else
1083 delete_insns_since (last);
1084 }
1085 }
1086 }
1087
1088 return 0;
1089}
1090\f
1091/* Generate code to perform an operation specified by UNOPTAB
1092 on operand OP0, with result having machine-mode MODE.
1093
1094 UNSIGNEDP is for the case where we have to widen the operands
1095 to perform the operation. It says to use zero-extension.
1096
1097 If TARGET is nonzero, the value
1098 is generated there, if it is convenient to do so.
1099 In all cases an rtx is returned for the locus of the value;
1100 this may or may not be TARGET. */
1101
1102rtx
1103expand_unop (mode, unoptab, op0, target, unsignedp)
1104 enum machine_mode mode;
1105 optab unoptab;
1106 rtx op0;
1107 rtx target;
1108 int unsignedp;
1109{
1110 enum mode_class class;
1111 enum machine_mode wider_mode;
77c9c6c2
RK
1112 register rtx temp;
1113 rtx last = get_last_insn ();
1114 rtx pat;
1115
1116 class = GET_MODE_CLASS (mode);
1117
1118 op0 = protect_from_queue (op0, 0);
1119
1120 if (flag_force_mem)
1121 {
1122 op0 = force_not_mem (op0);
1123 }
1124
1125 if (target)
1126 target = protect_from_queue (target, 1);
1127
1128 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1129 {
1130 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1131 enum machine_mode mode0 = insn_operand_mode[icode][1];
1132 rtx xop0 = op0;
1133
1134 if (target)
1135 temp = target;
1136 else
1137 temp = gen_reg_rtx (mode);
1138
1139 if (GET_MODE (xop0) != VOIDmode
1140 && GET_MODE (xop0) != mode0)
1141 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1142
1143 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1144
1145 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1146 xop0 = copy_to_mode_reg (mode0, xop0);
1147
1148 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1149 temp = gen_reg_rtx (mode);
1150
1151 pat = GEN_FCN (icode) (temp, xop0);
1152 if (pat)
1153 {
1154 if (GET_CODE (pat) == SEQUENCE
b1ec3c92 1155 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
77c9c6c2
RK
1156 {
1157 delete_insns_since (last);
b1ec3c92 1158 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
77c9c6c2
RK
1159 }
1160
1161 emit_insn (pat);
1162
1163 return temp;
1164 }
1165 else
1166 delete_insns_since (last);
1167 }
1168
9a856ec7
RK
1169 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1170
1171 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1172 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1173 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1174 {
1175 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1176 {
1177 rtx xop0 = op0;
1178
1179 /* For certain operations, we need not actually extend
1180 the narrow operand, as long as we will truncate the
1181 results to the same narrowness. */
1182
1183 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1184 && class == MODE_INT)
1185 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1186 else
1187 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1188
b1ec3c92
CH
1189 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1190 unsignedp);
9a856ec7
RK
1191
1192 if (temp)
1193 {
1194 if (class != MODE_INT)
1195 {
1196 if (target == 0)
1197 target = gen_reg_rtx (mode);
1198 convert_move (target, temp, 0);
1199 return target;
1200 }
1201 else
1202 return gen_lowpart (mode, temp);
1203 }
1204 else
1205 delete_insns_since (last);
1206 }
1207 }
1208
77c9c6c2
RK
1209 /* These can be done a word at a time. */
1210 if (unoptab == one_cmpl_optab
1211 && class == MODE_INT
1212 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
34e56753 1213 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2
RK
1214 {
1215 int i;
1216 rtx insns;
1217
1218 if (target == 0 || target == op0)
1219 target = gen_reg_rtx (mode);
1220
1221 start_sequence ();
1222
1223 /* Do the actual arithmetic. */
1224 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1225 {
1226 rtx target_piece = operand_subword (target, i, 1, mode);
34e56753 1227 rtx x = expand_unop (word_mode, unoptab,
77c9c6c2
RK
1228 operand_subword_force (op0, i, mode),
1229 target_piece, unsignedp);
1230 if (target_piece != x)
1231 emit_move_insn (target_piece, x);
1232 }
1233
1234 insns = get_insns ();
1235 end_sequence ();
1236
b1ec3c92 1237 emit_no_conflict_block (insns, target, op0, NULL_RTX,
77c9c6c2
RK
1238 gen_rtx (unoptab->code, mode, op0));
1239 return target;
1240 }
1241
1242 if (unoptab->handlers[(int) mode].libfunc)
1243 {
1244 rtx insns;
1245 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1246
1247 start_sequence ();
1248
1249 /* Pass 1 for NO_QUEUE so we don't lose any increments
1250 if the libcall is cse'd or moved. */
1251 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1252 1, mode, 1, op0, mode);
1253 insns = get_insns ();
1254 end_sequence ();
1255
1256 target = gen_reg_rtx (mode);
1257 emit_libcall_block (insns, target, hard_libcall_value (mode),
1258 gen_rtx (unoptab->code, mode, op0));
1259
1260 return target;
1261 }
1262
1263 /* It can't be done in this mode. Can we do it in a wider mode? */
1264
1265 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1266 {
34e56753 1267 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1268 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1269 {
1270 if ((unoptab->handlers[(int) wider_mode].insn_code
1271 != CODE_FOR_nothing)
1272 || unoptab->handlers[(int) wider_mode].libfunc)
1273 {
34e56753
RS
1274 rtx xop0 = op0;
1275
1276 /* For certain operations, we need not actually extend
1277 the narrow operand, as long as we will truncate the
1278 results to the same narrowness. */
1279
1280 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1281 && class == MODE_INT)
1282 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1283 else
1284 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
77c9c6c2 1285
b1ec3c92
CH
1286 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1287 unsignedp);
34e56753
RS
1288
1289 if (temp)
77c9c6c2 1290 {
34e56753
RS
1291 if (class != MODE_INT)
1292 {
1293 if (target == 0)
1294 target = gen_reg_rtx (mode);
1295 convert_move (target, temp, 0);
1296 return target;
1297 }
1298 else
1299 return gen_lowpart (mode, temp);
77c9c6c2
RK
1300 }
1301 else
34e56753 1302 delete_insns_since (last);
77c9c6c2
RK
1303 }
1304 }
1305 }
1306
1307 return 0;
1308}
1309\f
1310/* Generate an instruction whose insn-code is INSN_CODE,
1311 with two operands: an output TARGET and an input OP0.
1312 TARGET *must* be nonzero, and the output is always stored there.
1313 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1314 the value that is stored into TARGET. */
1315
1316void
1317emit_unop_insn (icode, target, op0, code)
1318 int icode;
1319 rtx target;
1320 rtx op0;
1321 enum rtx_code code;
1322{
1323 register rtx temp;
1324 enum machine_mode mode0 = insn_operand_mode[icode][1];
1325 rtx pat;
1326
1327 temp = target = protect_from_queue (target, 1);
1328
1329 op0 = protect_from_queue (op0, 0);
1330
1331 if (flag_force_mem)
1332 op0 = force_not_mem (op0);
1333
1334 /* Now, if insn does not accept our operands, put them into pseudos. */
1335
1336 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1337 op0 = copy_to_mode_reg (mode0, op0);
1338
1339 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1340 || (flag_force_mem && GET_CODE (temp) == MEM))
1341 temp = gen_reg_rtx (GET_MODE (temp));
1342
1343 pat = GEN_FCN (icode) (temp, op0);
1344
1345 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
b1ec3c92 1346 add_equal_note (pat, temp, code, op0, NULL_RTX);
77c9c6c2
RK
1347
1348 emit_insn (pat);
1349
1350 if (temp != target)
1351 emit_move_insn (target, temp);
1352}
1353\f
1354/* Emit code to perform a series of operations on a multi-word quantity, one
1355 word at a time.
1356
d45cf215 1357 Such a block is preceded by a CLOBBER of the output, consists of multiple
77c9c6c2
RK
1358 insns, each setting one word of the output, and followed by a SET copying
1359 the output to itself.
1360
1361 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1362 note indicating that it doesn't conflict with the (also multi-word)
1363 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1364 notes.
1365
1366 INSNS is a block of code generated to perform the operation, not including
1367 the CLOBBER and final copy. All insns that compute intermediate values
1368 are first emitted, followed by the block as described above. Only
1369 INSNs are allowed in the block; no library calls or jumps may be
1370 present.
1371
1372 TARGET, OP0, and OP1 are the output and inputs of the operations,
1373 respectively. OP1 may be zero for a unary operation.
1374
1375 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1376 on the last insn.
1377
1378 If TARGET is not a register, INSNS is simply emitted with no special
1379 processing.
1380
1381 The final insn emitted is returned. */
1382
1383rtx
1384emit_no_conflict_block (insns, target, op0, op1, equiv)
1385 rtx insns;
1386 rtx target;
1387 rtx op0, op1;
1388 rtx equiv;
1389{
1390 rtx prev, next, first, last, insn;
1391
1392 if (GET_CODE (target) != REG || reload_in_progress)
1393 return emit_insns (insns);
1394
1395 /* First emit all insns that do not store into words of the output and remove
1396 these from the list. */
1397 for (insn = insns; insn; insn = next)
1398 {
1399 rtx set = 0;
1400 int i;
1401
1402 next = NEXT_INSN (insn);
1403
1404 if (GET_CODE (insn) != INSN)
1405 abort ();
1406
1407 if (GET_CODE (PATTERN (insn)) == SET)
1408 set = PATTERN (insn);
1409 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1410 {
1411 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1412 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1413 {
1414 set = XVECEXP (PATTERN (insn), 0, i);
1415 break;
1416 }
1417 }
1418
1419 if (set == 0)
1420 abort ();
1421
1422 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1423 {
1424 if (PREV_INSN (insn))
1425 NEXT_INSN (PREV_INSN (insn)) = next;
1426 else
1427 insns = next;
1428
1429 if (next)
1430 PREV_INSN (next) = PREV_INSN (insn);
1431
1432 add_insn (insn);
1433 }
1434 }
1435
1436 prev = get_last_insn ();
1437
1438 /* Now write the CLOBBER of the output, followed by the setting of each
1439 of the words, followed by the final copy. */
1440 if (target != op0 && target != op1)
1441 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1442
1443 for (insn = insns; insn; insn = next)
1444 {
1445 next = NEXT_INSN (insn);
1446 add_insn (insn);
1447
1448 if (op1 && GET_CODE (op1) == REG)
1449 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1450 REG_NOTES (insn));
1451
1452 if (op0 && GET_CODE (op0) == REG)
1453 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1454 REG_NOTES (insn));
1455 }
1456
1457 last = emit_move_insn (target, target);
1458 if (equiv)
1459 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1460
1461 if (prev == 0)
1462 first = get_insns ();
1463 else
1464 first = NEXT_INSN (prev);
1465
1466 /* Encapsulate the block so it gets manipulated as a unit. */
1467 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1468 REG_NOTES (first));
1469 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1470
1471 return last;
1472}
1473\f
1474/* Emit code to make a call to a constant function or a library call.
1475
1476 INSNS is a list containing all insns emitted in the call.
1477 These insns leave the result in RESULT. Our block is to copy RESULT
1478 to TARGET, which is logically equivalent to EQUIV.
1479
1480 We first emit any insns that set a pseudo on the assumption that these are
1481 loading constants into registers; doing so allows them to be safely cse'ed
1482 between blocks. Then we emit all the other insns in the block, followed by
1483 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1484 note with an operand of EQUIV.
1485
29ebe69a
RK
1486 Moving assignments to pseudos outside of the block is done to improve
1487 the generated code, but is not required to generate correct code,
1488 hence being unable to move an assignment is not grounds for not making
1489 a libcall block. There are two reasons why it is safe to leave these
1490 insns inside the block: First, we know that these pseudos cannot be
1491 used in generated RTL outside the block since they are created for
1492 temporary purposes within the block. Second, CSE will not record the
1493 values of anything set inside a libcall block, so we know they must
1494 be dead at the end of the block.
1495
77c9c6c2
RK
1496 Except for the first group of insns (the ones setting pseudos), the
1497 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1498
1499void
1500emit_libcall_block (insns, target, result, equiv)
1501 rtx insns;
1502 rtx target;
1503 rtx result;
1504 rtx equiv;
1505{
1506 rtx prev, next, first, last, insn;
1507
1508 /* First emit all insns that set pseudos. Remove them from the list as
29ebe69a
RK
1509 we go. Avoid insns that set pseudo which were referenced in previous
1510 insns. These can be generated by move_by_pieces, for example,
1511 to update an address. */
77c9c6c2
RK
1512
1513 for (insn = insns; insn; insn = next)
1514 {
1515 rtx set = single_set (insn);
1516
1517 next = NEXT_INSN (insn);
1518
1519 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
29ebe69a 1520 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
8d9e73cc
RS
1521 && (insn == insns
1522 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1523 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
77c9c6c2
RK
1524 {
1525 if (PREV_INSN (insn))
1526 NEXT_INSN (PREV_INSN (insn)) = next;
1527 else
1528 insns = next;
1529
1530 if (next)
1531 PREV_INSN (next) = PREV_INSN (insn);
1532
1533 add_insn (insn);
1534 }
1535 }
1536
1537 prev = get_last_insn ();
1538
1539 /* Write the remaining insns followed by the final copy. */
1540
1541 for (insn = insns; insn; insn = next)
1542 {
1543 next = NEXT_INSN (insn);
1544
1545 add_insn (insn);
1546 }
1547
1548 last = emit_move_insn (target, result);
1549 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1550
1551 if (prev == 0)
1552 first = get_insns ();
1553 else
1554 first = NEXT_INSN (prev);
1555
1556 /* Encapsulate the block so it gets manipulated as a unit. */
1557 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1558 REG_NOTES (first));
1559 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1560}
1561\f
1562/* Generate code to store zero in X. */
1563
1564void
1565emit_clr_insn (x)
1566 rtx x;
1567{
1568 emit_move_insn (x, const0_rtx);
1569}
1570
1571/* Generate code to store 1 in X
1572 assuming it contains zero beforehand. */
1573
1574void
1575emit_0_to_1_insn (x)
1576 rtx x;
1577{
1578 emit_move_insn (x, const1_rtx);
1579}
1580
1581/* Generate code to compare X with Y
1582 so that the condition codes are set.
1583
1584 MODE is the mode of the inputs (in case they are const_int).
1585 UNSIGNEDP nonzero says that X and Y are unsigned;
1586 this matters if they need to be widened.
1587
1588 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1589 and ALIGN specifies the known shared alignment of X and Y.
1590
1591 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1592 It is ignored for fixed-point and block comparisons;
1593 it is used only for floating-point comparisons. */
1594
1595void
1596emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1597 rtx x, y;
1598 enum rtx_code comparison;
1599 rtx size;
2aa8f23f 1600 enum machine_mode mode;
77c9c6c2
RK
1601 int unsignedp;
1602 int align;
1603{
1604 enum mode_class class;
1605 enum machine_mode wider_mode;
1606
1607 class = GET_MODE_CLASS (mode);
1608
1609 /* They could both be VOIDmode if both args are immediate constants,
1610 but we should fold that at an earlier stage.
1611 With no special code here, this will call abort,
1612 reminding the programmer to implement such folding. */
1613
1614 if (mode != BLKmode && flag_force_mem)
1615 {
1616 x = force_not_mem (x);
1617 y = force_not_mem (y);
1618 }
1619
1620 /* If we are inside an appropriately-short loop and one operand is an
1621 expensive constant, force it into a register. */
aeedc93f 1622 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
77c9c6c2
RK
1623 x = force_reg (mode, x);
1624
aeedc93f 1625 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
77c9c6c2
RK
1626 y = force_reg (mode, y);
1627
1628 /* Don't let both operands fail to indicate the mode. */
1629 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1630 x = force_reg (mode, x);
1631
1632 /* Handle all BLKmode compares. */
1633
1634 if (mode == BLKmode)
1635 {
1636 emit_queue ();
1637 x = protect_from_queue (x, 0);
1638 y = protect_from_queue (y, 0);
1639
1640 if (size == 0)
1641 abort ();
1642#ifdef HAVE_cmpstrqi
1643 if (HAVE_cmpstrqi
1644 && GET_CODE (size) == CONST_INT
1645 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1646 {
1647 enum machine_mode result_mode
1648 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1649 rtx result = gen_reg_rtx (result_mode);
b1ec3c92
CH
1650 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
1651 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1652 result_mode, 0, 0);
77c9c6c2
RK
1653 }
1654 else
1655#endif
1656#ifdef HAVE_cmpstrhi
1657 if (HAVE_cmpstrhi
1658 && GET_CODE (size) == CONST_INT
1659 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1660 {
1661 enum machine_mode result_mode
1662 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1663 rtx result = gen_reg_rtx (result_mode);
b1ec3c92
CH
1664 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
1665 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1666 result_mode, 0, 0);
77c9c6c2
RK
1667 }
1668 else
1669#endif
1670#ifdef HAVE_cmpstrsi
1671 if (HAVE_cmpstrsi)
1672 {
1673 enum machine_mode result_mode
1674 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1675 rtx result = gen_reg_rtx (result_mode);
06e40b26 1676 size = protect_from_queue (size, 0);
77c9c6c2
RK
1677 emit_insn (gen_cmpstrsi (result, x, y,
1678 convert_to_mode (SImode, size, 1),
b1ec3c92
CH
1679 GEN_INT (align)));
1680 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1681 result_mode, 0, 0);
77c9c6c2
RK
1682 }
1683 else
1684#endif
1685 {
1686#ifdef TARGET_MEM_FUNCTIONS
86f8eff3 1687 emit_library_call (memcmp_libfunc, 1,
77c9c6c2
RK
1688 TYPE_MODE (integer_type_node), 3,
1689 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1690 size, Pmode);
1691#else
86f8eff3 1692 emit_library_call (bcmp_libfunc, 1,
77c9c6c2
RK
1693 TYPE_MODE (integer_type_node), 3,
1694 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1695 size, Pmode);
1696#endif
1697 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
b1ec3c92 1698 const0_rtx, comparison, NULL_RTX,
77c9c6c2
RK
1699 TYPE_MODE (integer_type_node), 0, 0);
1700 }
1701 return;
1702 }
1703
1704 /* Handle some compares against zero. */
1705
1706 if (y == CONST0_RTX (mode)
1707 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1708 {
1709 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1710
1711 emit_queue ();
1712 x = protect_from_queue (x, 0);
1713 y = protect_from_queue (y, 0);
1714
1715 /* Now, if insn does accept these operands, put them into pseudos. */
1716 if (! (*insn_operand_predicate[icode][0])
1717 (x, insn_operand_mode[icode][0]))
1718 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1719
1720 emit_insn (GEN_FCN (icode) (x));
1721 return;
1722 }
1723
1724 /* Handle compares for which there is a directly suitable insn. */
1725
1726 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1727 {
1728 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1729
1730 emit_queue ();
1731 x = protect_from_queue (x, 0);
1732 y = protect_from_queue (y, 0);
1733
1734 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1735 if (! (*insn_operand_predicate[icode][0])
1736 (x, insn_operand_mode[icode][0]))
1737 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1738
1739 if (! (*insn_operand_predicate[icode][1])
1740 (y, insn_operand_mode[icode][1]))
1741 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1742
1743 emit_insn (GEN_FCN (icode) (x, y));
1744 return;
1745 }
1746
1747 /* Try widening if we can find a direct insn that way. */
1748
1749 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1750 {
34e56753 1751 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1752 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1753 {
1754 if (cmp_optab->handlers[(int) wider_mode].insn_code
1755 != CODE_FOR_nothing)
1756 {
06e40b26
RS
1757 x = protect_from_queue (x, 0);
1758 y = protect_from_queue (y, 0);
77c9c6c2
RK
1759 x = convert_to_mode (wider_mode, x, unsignedp);
1760 y = convert_to_mode (wider_mode, y, unsignedp);
b1ec3c92 1761 emit_cmp_insn (x, y, comparison, NULL_RTX,
77c9c6c2
RK
1762 wider_mode, unsignedp, align);
1763 return;
1764 }
1765 }
1766 }
1767
1768 /* Handle a lib call just for the mode we are using. */
1769
1770 if (cmp_optab->handlers[(int) mode].libfunc
1771 && class != MODE_FLOAT)
1772 {
1773 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1774 /* If we want unsigned, and this mode has a distinct unsigned
1775 comparison routine, use that. */
1776 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1777 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1778
86f8eff3 1779 emit_library_call (libfunc, 1,
77c9c6c2
RK
1780 SImode, 2, x, mode, y, mode);
1781
1782 /* Integer comparison returns a result that must be compared against 1,
1783 so that even if we do an unsigned compare afterward,
1784 there is still a value that can represent the result "less than". */
1785
1786 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
b1ec3c92 1787 comparison, NULL_RTX, SImode, unsignedp, 0);
77c9c6c2
RK
1788 return;
1789 }
1790
1791 if (class == MODE_FLOAT)
1792 emit_float_lib_cmp (x, y, comparison);
1793
1794 else
1795 abort ();
1796}
1797
1798/* Nonzero if a compare of mode MODE can be done straightforwardly
1799 (without splitting it into pieces). */
1800
1801int
1802can_compare_p (mode)
1803 enum machine_mode mode;
1804{
1805 do
1806 {
1807 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1808 return 1;
1809 mode = GET_MODE_WIDER_MODE (mode);
1810 } while (mode != VOIDmode);
1811
1812 return 0;
1813}
1814\f
1815/* Emit a library call comparison between floating point X and Y.
1816 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1817
1818static void
1819emit_float_lib_cmp (x, y, comparison)
1820 rtx x, y;
1821 enum rtx_code comparison;
1822{
1823 enum machine_mode mode = GET_MODE (x);
1824 rtx libfunc;
1825
1826 if (mode == SFmode)
1827 switch (comparison)
1828 {
1829 case EQ:
1830 libfunc = eqsf2_libfunc;
1831 break;
1832
1833 case NE:
1834 libfunc = nesf2_libfunc;
1835 break;
1836
1837 case GT:
1838 libfunc = gtsf2_libfunc;
1839 break;
1840
1841 case GE:
1842 libfunc = gesf2_libfunc;
1843 break;
1844
1845 case LT:
1846 libfunc = ltsf2_libfunc;
1847 break;
1848
1849 case LE:
1850 libfunc = lesf2_libfunc;
1851 break;
1852 }
1853 else if (mode == DFmode)
1854 switch (comparison)
1855 {
1856 case EQ:
1857 libfunc = eqdf2_libfunc;
1858 break;
1859
1860 case NE:
1861 libfunc = nedf2_libfunc;
1862 break;
1863
1864 case GT:
1865 libfunc = gtdf2_libfunc;
1866 break;
1867
1868 case GE:
1869 libfunc = gedf2_libfunc;
1870 break;
1871
1872 case LT:
1873 libfunc = ltdf2_libfunc;
1874 break;
1875
1876 case LE:
1877 libfunc = ledf2_libfunc;
1878 break;
1879 }
b092b471
JW
1880 else if (mode == XFmode)
1881 switch (comparison)
1882 {
1883 case EQ:
1884 libfunc = eqxf2_libfunc;
1885 break;
1886
1887 case NE:
1888 libfunc = nexf2_libfunc;
1889 break;
1890
1891 case GT:
1892 libfunc = gtxf2_libfunc;
1893 break;
1894
1895 case GE:
1896 libfunc = gexf2_libfunc;
1897 break;
1898
1899 case LT:
1900 libfunc = ltxf2_libfunc;
1901 break;
1902
1903 case LE:
1904 libfunc = lexf2_libfunc;
1905 break;
1906 }
1907 else if (mode == TFmode)
1908 switch (comparison)
1909 {
1910 case EQ:
1911 libfunc = eqtf2_libfunc;
1912 break;
1913
1914 case NE:
1915 libfunc = netf2_libfunc;
1916 break;
1917
1918 case GT:
1919 libfunc = gttf2_libfunc;
1920 break;
1921
1922 case GE:
1923 libfunc = getf2_libfunc;
1924 break;
1925
1926 case LT:
1927 libfunc = lttf2_libfunc;
1928 break;
1929
1930 case LE:
1931 libfunc = letf2_libfunc;
1932 break;
1933 }
77c9c6c2
RK
1934 else
1935 {
1936 enum machine_mode wider_mode;
1937
34e56753 1938 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1939 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1940 {
1941 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1942 != CODE_FOR_nothing)
1943 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1944 {
06e40b26
RS
1945 x = protect_from_queue (x, 0);
1946 y = protect_from_queue (y, 0);
77c9c6c2
RK
1947 x = convert_to_mode (wider_mode, x, 0);
1948 y = convert_to_mode (wider_mode, y, 0);
1949 emit_float_lib_cmp (x, y, comparison);
1950 return;
1951 }
1952 }
1953 abort ();
1954 }
1955
86f8eff3 1956 emit_library_call (libfunc, 1,
77c9c6c2
RK
1957 SImode, 2, x, mode, y, mode);
1958
1959 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
b1ec3c92 1960 NULL_RTX, SImode, 0, 0);
77c9c6c2
RK
1961}
1962\f
1963/* Generate code to indirectly jump to a location given in the rtx LOC. */
1964
1965void
1966emit_indirect_jump (loc)
1967 rtx loc;
1968{
1969 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1970 (loc, VOIDmode)))
1971 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1972 loc);
1973
1974 emit_jump_insn (gen_indirect_jump (loc));
9649fb4d 1975 emit_barrier ();
77c9c6c2
RK
1976}
1977\f
1978/* These three functions generate an insn body and return it
1979 rather than emitting the insn.
1980
1981 They do not protect from queued increments,
1982 because they may be used 1) in protect_from_queue itself
1983 and 2) in other passes where there is no queue. */
1984
1985/* Generate and return an insn body to add Y to X. */
1986
1987rtx
1988gen_add2_insn (x, y)
1989 rtx x, y;
1990{
1991 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1992
1993 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1994 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1995 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1996 abort ();
1997
1998 return (GEN_FCN (icode) (x, x, y));
1999}
2000
2001int
2002have_add2_insn (mode)
2003 enum machine_mode mode;
2004{
2005 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2006}
2007
2008/* Generate and return an insn body to subtract Y from X. */
2009
2010rtx
2011gen_sub2_insn (x, y)
2012 rtx x, y;
2013{
2014 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2015
2016 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2017 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2018 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2019 abort ();
2020
2021 return (GEN_FCN (icode) (x, x, y));
2022}
2023
2024int
2025have_sub2_insn (mode)
2026 enum machine_mode mode;
2027{
2028 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2029}
2030
2031/* Generate the body of an instruction to copy Y into X. */
2032
2033rtx
2034gen_move_insn (x, y)
2035 rtx x, y;
2036{
2037 register enum machine_mode mode = GET_MODE (x);
2038 enum insn_code insn_code;
2039
2040 if (mode == VOIDmode)
2041 mode = GET_MODE (y);
2042
2043 insn_code = mov_optab->handlers[(int) mode].insn_code;
2044
2045 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2046 find a mode to do it in. If we have a movcc, use it. Otherwise,
2047 find the MODE_INT mode of the same width. */
2048
2049 if (insn_code == CODE_FOR_nothing)
2050 {
2051 enum machine_mode tmode = VOIDmode;
2052 rtx x1 = x, y1 = y;
2053
2054 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2055 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2056 tmode = CCmode;
2057 else if (GET_MODE_CLASS (mode) == MODE_CC)
2058 for (tmode = QImode; tmode != VOIDmode;
2059 tmode = GET_MODE_WIDER_MODE (tmode))
2060 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2061 break;
2062
2063 if (tmode == VOIDmode)
2064 abort ();
2065
2066 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2067 may call change_address which is not appropriate if we were
2068 called when a reload was in progress. We don't have to worry
2069 about changing the address since the size in bytes is supposed to
2070 be the same. Copy the MEM to change the mode and move any
2071 substitutions from the old MEM to the new one. */
2072
2073 if (reload_in_progress)
2074 {
2075 x = gen_lowpart_common (tmode, x1);
2076 if (x == 0 && GET_CODE (x1) == MEM)
2077 {
2078 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2079 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2080 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2081 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2082 copy_replacements (x1, x);
2083 }
2084
2085 y = gen_lowpart_common (tmode, y1);
2086 if (y == 0 && GET_CODE (y1) == MEM)
2087 {
2088 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2089 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2090 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2091 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2092 copy_replacements (y1, y);
2093 }
2094 }
2095 else
2096 {
2097 x = gen_lowpart (tmode, x);
2098 y = gen_lowpart (tmode, y);
2099 }
2100
2101 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2102 }
2103
2104 return (GEN_FCN (insn_code) (x, y));
2105}
2106\f
2107/* Tables of patterns for extending one integer mode to another. */
34e56753 2108static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
77c9c6c2 2109
34e56753
RS
2110/* Return the insn code used to extend FROM_MODE to TO_MODE.
2111 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2112 no such operation exists, CODE_FOR_nothing will be returned. */
77c9c6c2 2113
34e56753 2114enum insn_code
77c9c6c2
RK
2115can_extend_p (to_mode, from_mode, unsignedp)
2116 enum machine_mode to_mode, from_mode;
2117 int unsignedp;
2118{
34e56753 2119 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
77c9c6c2
RK
2120}
2121
2122/* Generate the body of an insn to extend Y (with mode MFROM)
2123 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2124
2125rtx
2126gen_extend_insn (x, y, mto, mfrom, unsignedp)
2127 rtx x, y;
2128 enum machine_mode mto, mfrom;
2129 int unsignedp;
2130{
34e56753 2131 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
77c9c6c2
RK
2132}
2133
2134static void
2135init_extends ()
2136{
34e56753
RS
2137 enum insn_code *p;
2138
2139 for (p = extendtab[0][0];
2140 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2141 p++)
2142 *p = CODE_FOR_nothing;
77c9c6c2
RK
2143
2144#ifdef HAVE_extendditi2
2145 if (HAVE_extendditi2)
34e56753 2146 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
77c9c6c2
RK
2147#endif
2148#ifdef HAVE_extendsiti2
2149 if (HAVE_extendsiti2)
34e56753 2150 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
77c9c6c2
RK
2151#endif
2152#ifdef HAVE_extendhiti2
2153 if (HAVE_extendhiti2)
34e56753 2154 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
77c9c6c2
RK
2155#endif
2156#ifdef HAVE_extendqiti2
2157 if (HAVE_extendqiti2)
34e56753 2158 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
77c9c6c2
RK
2159#endif
2160#ifdef HAVE_extendsidi2
2161 if (HAVE_extendsidi2)
34e56753 2162 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
77c9c6c2
RK
2163#endif
2164#ifdef HAVE_extendhidi2
2165 if (HAVE_extendhidi2)
34e56753 2166 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
77c9c6c2
RK
2167#endif
2168#ifdef HAVE_extendqidi2
2169 if (HAVE_extendqidi2)
34e56753 2170 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
77c9c6c2
RK
2171#endif
2172#ifdef HAVE_extendhisi2
2173 if (HAVE_extendhisi2)
34e56753 2174 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
77c9c6c2
RK
2175#endif
2176#ifdef HAVE_extendqisi2
2177 if (HAVE_extendqisi2)
34e56753 2178 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
77c9c6c2
RK
2179#endif
2180#ifdef HAVE_extendqihi2
2181 if (HAVE_extendqihi2)
34e56753 2182 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
77c9c6c2
RK
2183#endif
2184
2185#ifdef HAVE_zero_extendditi2
2186 if (HAVE_zero_extendsiti2)
34e56753 2187 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
77c9c6c2
RK
2188#endif
2189#ifdef HAVE_zero_extendsiti2
2190 if (HAVE_zero_extendsiti2)
34e56753 2191 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
77c9c6c2
RK
2192#endif
2193#ifdef HAVE_zero_extendhiti2
2194 if (HAVE_zero_extendhiti2)
34e56753 2195 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
77c9c6c2
RK
2196#endif
2197#ifdef HAVE_zero_extendqiti2
2198 if (HAVE_zero_extendqiti2)
34e56753 2199 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
77c9c6c2
RK
2200#endif
2201#ifdef HAVE_zero_extendsidi2
2202 if (HAVE_zero_extendsidi2)
34e56753 2203 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
77c9c6c2
RK
2204#endif
2205#ifdef HAVE_zero_extendhidi2
2206 if (HAVE_zero_extendhidi2)
34e56753 2207 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
77c9c6c2
RK
2208#endif
2209#ifdef HAVE_zero_extendqidi2
2210 if (HAVE_zero_extendqidi2)
34e56753 2211 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
77c9c6c2
RK
2212#endif
2213#ifdef HAVE_zero_extendhisi2
2214 if (HAVE_zero_extendhisi2)
34e56753 2215 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
77c9c6c2
RK
2216#endif
2217#ifdef HAVE_zero_extendqisi2
2218 if (HAVE_zero_extendqisi2)
34e56753 2219 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
77c9c6c2
RK
2220#endif
2221#ifdef HAVE_zero_extendqihi2
2222 if (HAVE_zero_extendqihi2)
34e56753 2223 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
77c9c6c2
RK
2224#endif
2225}
2226\f
2227/* can_fix_p and can_float_p say whether the target machine
2228 can directly convert a given fixed point type to
2229 a given floating point type, or vice versa.
2230 The returned value is the CODE_FOR_... value to use,
2231 or CODE_FOR_nothing if these modes cannot be directly converted. */
2232
2233static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2234static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2235static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2236
2237/* *TRUNCP_PTR is set to 1 if it is necessary to output
2238 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2239
2240static enum insn_code
2241can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2242 enum machine_mode fltmode, fixmode;
2243 int unsignedp;
2244 int *truncp_ptr;
2245{
2246 *truncp_ptr = 0;
2247 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2248 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2249
2250 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2251 {
2252 *truncp_ptr = 1;
2253 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2254 }
2255 return CODE_FOR_nothing;
2256}
2257
2258static enum insn_code
2259can_float_p (fltmode, fixmode, unsignedp)
2260 enum machine_mode fixmode, fltmode;
2261 int unsignedp;
2262{
2263 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2264}
2265
2266void
2267init_fixtab ()
2268{
2269 enum insn_code *p;
2270 for (p = fixtab[0][0];
2271 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2272 p++)
2273 *p = CODE_FOR_nothing;
2274 for (p = fixtrunctab[0][0];
2275 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2276 p++)
2277 *p = CODE_FOR_nothing;
2278
2279#ifdef HAVE_fixsfqi2
2280 if (HAVE_fixsfqi2)
2281 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2282#endif
2283#ifdef HAVE_fixsfhi2
2284 if (HAVE_fixsfhi2)
2285 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2286#endif
2287#ifdef HAVE_fixsfsi2
2288 if (HAVE_fixsfsi2)
2289 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2290#endif
2291#ifdef HAVE_fixsfdi2
2292 if (HAVE_fixsfdi2)
2293 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2294#endif
2295
2296#ifdef HAVE_fixdfqi2
2297 if (HAVE_fixdfqi2)
2298 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2299#endif
2300#ifdef HAVE_fixdfhi2
2301 if (HAVE_fixdfhi2)
2302 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2303#endif
2304#ifdef HAVE_fixdfsi2
2305 if (HAVE_fixdfsi2)
2306 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2307#endif
2308#ifdef HAVE_fixdfdi2
2309 if (HAVE_fixdfdi2)
2310 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2311#endif
2312#ifdef HAVE_fixdfti2
2313 if (HAVE_fixdfti2)
2314 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2315#endif
2316
b092b471
JW
2317#ifdef HAVE_fixxfqi2
2318 if (HAVE_fixxfqi2)
2319 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2320#endif
2321#ifdef HAVE_fixxfhi2
2322 if (HAVE_fixxfhi2)
2323 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2324#endif
2325#ifdef HAVE_fixxfsi2
2326 if (HAVE_fixxfsi2)
2327 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2328#endif
2329#ifdef HAVE_fixxfdi2
2330 if (HAVE_fixxfdi2)
2331 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2332#endif
2333#ifdef HAVE_fixxfti2
2334 if (HAVE_fixxfti2)
2335 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2336#endif
2337
77c9c6c2
RK
2338#ifdef HAVE_fixtfqi2
2339 if (HAVE_fixtfqi2)
2340 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2341#endif
2342#ifdef HAVE_fixtfhi2
2343 if (HAVE_fixtfhi2)
2344 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2345#endif
2346#ifdef HAVE_fixtfsi2
2347 if (HAVE_fixtfsi2)
2348 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2349#endif
2350#ifdef HAVE_fixtfdi2
2351 if (HAVE_fixtfdi2)
2352 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2353#endif
2354#ifdef HAVE_fixtfti2
2355 if (HAVE_fixtfti2)
2356 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2357#endif
2358
2359#ifdef HAVE_fixunssfqi2
2360 if (HAVE_fixunssfqi2)
2361 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2362#endif
2363#ifdef HAVE_fixunssfhi2
2364 if (HAVE_fixunssfhi2)
2365 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2366#endif
2367#ifdef HAVE_fixunssfsi2
2368 if (HAVE_fixunssfsi2)
2369 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2370#endif
2371#ifdef HAVE_fixunssfdi2
2372 if (HAVE_fixunssfdi2)
2373 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2374#endif
2375
2376#ifdef HAVE_fixunsdfqi2
2377 if (HAVE_fixunsdfqi2)
2378 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2379#endif
2380#ifdef HAVE_fixunsdfhi2
2381 if (HAVE_fixunsdfhi2)
2382 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2383#endif
2384#ifdef HAVE_fixunsdfsi2
2385 if (HAVE_fixunsdfsi2)
2386 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2387#endif
2388#ifdef HAVE_fixunsdfdi2
2389 if (HAVE_fixunsdfdi2)
2390 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2391#endif
2392#ifdef HAVE_fixunsdfti2
2393 if (HAVE_fixunsdfti2)
2394 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2395#endif
2396
b092b471
JW
2397#ifdef HAVE_fixunsxfqi2
2398 if (HAVE_fixunsxfqi2)
2399 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2400#endif
2401#ifdef HAVE_fixunsxfhi2
2402 if (HAVE_fixunsxfhi2)
2403 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2404#endif
2405#ifdef HAVE_fixunsxfsi2
2406 if (HAVE_fixunsxfsi2)
2407 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2408#endif
2409#ifdef HAVE_fixunsxfdi2
2410 if (HAVE_fixunsxfdi2)
2411 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2412#endif
2413#ifdef HAVE_fixunsxfti2
2414 if (HAVE_fixunsxfti2)
2415 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2416#endif
2417
77c9c6c2
RK
2418#ifdef HAVE_fixunstfqi2
2419 if (HAVE_fixunstfqi2)
2420 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2421#endif
2422#ifdef HAVE_fixunstfhi2
2423 if (HAVE_fixunstfhi2)
2424 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2425#endif
2426#ifdef HAVE_fixunstfsi2
2427 if (HAVE_fixunstfsi2)
2428 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2429#endif
2430#ifdef HAVE_fixunstfdi2
2431 if (HAVE_fixunstfdi2)
2432 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2433#endif
2434#ifdef HAVE_fixunstfti2
2435 if (HAVE_fixunstfti2)
2436 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2437#endif
2438
2439#ifdef HAVE_fix_truncsfqi2
2440 if (HAVE_fix_truncsfqi2)
2441 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2442#endif
2443#ifdef HAVE_fix_truncsfhi2
2444 if (HAVE_fix_truncsfhi2)
2445 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2446#endif
2447#ifdef HAVE_fix_truncsfsi2
2448 if (HAVE_fix_truncsfsi2)
2449 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2450#endif
2451#ifdef HAVE_fix_truncsfdi2
2452 if (HAVE_fix_truncsfdi2)
2453 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2454#endif
2455
2456#ifdef HAVE_fix_truncdfqi2
2457 if (HAVE_fix_truncdfsi2)
2458 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2459#endif
2460#ifdef HAVE_fix_truncdfhi2
2461 if (HAVE_fix_truncdfhi2)
2462 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2463#endif
2464#ifdef HAVE_fix_truncdfsi2
2465 if (HAVE_fix_truncdfsi2)
2466 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2467#endif
2468#ifdef HAVE_fix_truncdfdi2
2469 if (HAVE_fix_truncdfdi2)
2470 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2471#endif
2472#ifdef HAVE_fix_truncdfti2
2473 if (HAVE_fix_truncdfti2)
2474 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2475#endif
2476
b092b471
JW
2477#ifdef HAVE_fix_truncxfqi2
2478 if (HAVE_fix_truncxfqi2)
2479 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2480#endif
2481#ifdef HAVE_fix_truncxfhi2
2482 if (HAVE_fix_truncxfhi2)
2483 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2484#endif
2485#ifdef HAVE_fix_truncxfsi2
2486 if (HAVE_fix_truncxfsi2)
2487 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2488#endif
2489#ifdef HAVE_fix_truncxfdi2
2490 if (HAVE_fix_truncxfdi2)
2491 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2492#endif
2493#ifdef HAVE_fix_truncxfti2
2494 if (HAVE_fix_truncxfti2)
2495 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2496#endif
2497
77c9c6c2
RK
2498#ifdef HAVE_fix_trunctfqi2
2499 if (HAVE_fix_trunctfqi2)
2500 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2501#endif
2502#ifdef HAVE_fix_trunctfhi2
2503 if (HAVE_fix_trunctfhi2)
2504 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2505#endif
2506#ifdef HAVE_fix_trunctfsi2
2507 if (HAVE_fix_trunctfsi2)
2508 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2509#endif
2510#ifdef HAVE_fix_trunctfdi2
2511 if (HAVE_fix_trunctfdi2)
2512 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2513#endif
2514#ifdef HAVE_fix_trunctfti2
2515 if (HAVE_fix_trunctfti2)
2516 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2517#endif
2518
2519#ifdef HAVE_fixuns_truncsfqi2
2520 if (HAVE_fixuns_truncsfqi2)
2521 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2522#endif
2523#ifdef HAVE_fixuns_truncsfhi2
2524 if (HAVE_fixuns_truncsfhi2)
2525 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2526#endif
2527#ifdef HAVE_fixuns_truncsfsi2
2528 if (HAVE_fixuns_truncsfsi2)
2529 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2530#endif
2531#ifdef HAVE_fixuns_truncsfdi2
2532 if (HAVE_fixuns_truncsfdi2)
2533 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2534#endif
2535
2536#ifdef HAVE_fixuns_truncdfqi2
2537 if (HAVE_fixuns_truncdfqi2)
2538 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2539#endif
2540#ifdef HAVE_fixuns_truncdfhi2
2541 if (HAVE_fixuns_truncdfhi2)
2542 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2543#endif
2544#ifdef HAVE_fixuns_truncdfsi2
2545 if (HAVE_fixuns_truncdfsi2)
2546 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2547#endif
2548#ifdef HAVE_fixuns_truncdfdi2
2549 if (HAVE_fixuns_truncdfdi2)
2550 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2551#endif
2552#ifdef HAVE_fixuns_truncdfti2
2553 if (HAVE_fixuns_truncdfti2)
2554 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2555#endif
2556
b092b471
JW
2557#ifdef HAVE_fixuns_truncxfqi2
2558 if (HAVE_fixuns_truncxfqi2)
2559 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2560#endif
2561#ifdef HAVE_fixuns_truncxfhi2
2562 if (HAVE_fixuns_truncxfhi2)
2563 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2564#endif
2565#ifdef HAVE_fixuns_truncxfsi2
2566 if (HAVE_fixuns_truncxfsi2)
2567 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2568#endif
2569#ifdef HAVE_fixuns_truncxfdi2
2570 if (HAVE_fixuns_truncxfdi2)
2571 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2572#endif
2573#ifdef HAVE_fixuns_truncxfti2
2574 if (HAVE_fixuns_truncxfti2)
2575 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2576#endif
2577
77c9c6c2
RK
2578#ifdef HAVE_fixuns_trunctfqi2
2579 if (HAVE_fixuns_trunctfqi2)
2580 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2581#endif
2582#ifdef HAVE_fixuns_trunctfhi2
2583 if (HAVE_fixuns_trunctfhi2)
2584 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2585#endif
2586#ifdef HAVE_fixuns_trunctfsi2
2587 if (HAVE_fixuns_trunctfsi2)
2588 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2589#endif
2590#ifdef HAVE_fixuns_trunctfdi2
2591 if (HAVE_fixuns_trunctfdi2)
2592 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2593#endif
2594#ifdef HAVE_fixuns_trunctfti2
2595 if (HAVE_fixuns_trunctfti2)
2596 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2597#endif
2598
2599#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2600 /* This flag says the same insns that convert to a signed fixnum
2601 also convert validly to an unsigned one. */
2602 {
2603 int i;
2604 int j;
2605 for (i = 0; i < NUM_MACHINE_MODES; i++)
2606 for (j = 0; j < NUM_MACHINE_MODES; j++)
2607 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2608 }
2609#endif
2610}
2611
2612void
2613init_floattab ()
2614{
2615 enum insn_code *p;
2616 for (p = floattab[0][0];
2617 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2618 p++)
2619 *p = CODE_FOR_nothing;
2620
2621#ifdef HAVE_floatqisf2
2622 if (HAVE_floatqisf2)
2623 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2624#endif
2625#ifdef HAVE_floathisf2
2626 if (HAVE_floathisf2)
2627 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2628#endif
2629#ifdef HAVE_floatsisf2
2630 if (HAVE_floatsisf2)
2631 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2632#endif
2633#ifdef HAVE_floatdisf2
2634 if (HAVE_floatdisf2)
2635 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2636#endif
2637#ifdef HAVE_floattisf2
2638 if (HAVE_floattisf2)
2639 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2640#endif
2641
2642#ifdef HAVE_floatqidf2
2643 if (HAVE_floatqidf2)
2644 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2645#endif
2646#ifdef HAVE_floathidf2
2647 if (HAVE_floathidf2)
2648 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2649#endif
2650#ifdef HAVE_floatsidf2
2651 if (HAVE_floatsidf2)
2652 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2653#endif
2654#ifdef HAVE_floatdidf2
2655 if (HAVE_floatdidf2)
2656 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2657#endif
2658#ifdef HAVE_floattidf2
2659 if (HAVE_floattidf2)
2660 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2661#endif
2662
b092b471
JW
2663#ifdef HAVE_floatqixf2
2664 if (HAVE_floatqixf2)
2665 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2666#endif
2667#ifdef HAVE_floathixf2
2668 if (HAVE_floathixf2)
2669 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2670#endif
2671#ifdef HAVE_floatsixf2
2672 if (HAVE_floatsixf2)
2673 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2674#endif
2675#ifdef HAVE_floatdixf2
2676 if (HAVE_floatdixf2)
2677 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2678#endif
2679#ifdef HAVE_floattixf2
2680 if (HAVE_floattixf2)
2681 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2682#endif
2683
77c9c6c2
RK
2684#ifdef HAVE_floatqitf2
2685 if (HAVE_floatqitf2)
2686 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2687#endif
2688#ifdef HAVE_floathitf2
2689 if (HAVE_floathitf2)
2690 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2691#endif
2692#ifdef HAVE_floatsitf2
2693 if (HAVE_floatsitf2)
2694 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2695#endif
2696#ifdef HAVE_floatditf2
2697 if (HAVE_floatditf2)
2698 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2699#endif
2700#ifdef HAVE_floattitf2
2701 if (HAVE_floattitf2)
2702 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2703#endif
2704
2705#ifdef HAVE_floatunsqisf2
2706 if (HAVE_floatunsqisf2)
2707 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2708#endif
2709#ifdef HAVE_floatunshisf2
2710 if (HAVE_floatunshisf2)
2711 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2712#endif
2713#ifdef HAVE_floatunssisf2
2714 if (HAVE_floatunssisf2)
2715 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2716#endif
2717#ifdef HAVE_floatunsdisf2
2718 if (HAVE_floatunsdisf2)
2719 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2720#endif
2721#ifdef HAVE_floatunstisf2
2722 if (HAVE_floatunstisf2)
2723 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2724#endif
2725
2726#ifdef HAVE_floatunsqidf2
2727 if (HAVE_floatunsqidf2)
2728 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2729#endif
2730#ifdef HAVE_floatunshidf2
2731 if (HAVE_floatunshidf2)
2732 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2733#endif
2734#ifdef HAVE_floatunssidf2
2735 if (HAVE_floatunssidf2)
2736 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2737#endif
2738#ifdef HAVE_floatunsdidf2
2739 if (HAVE_floatunsdidf2)
2740 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2741#endif
2742#ifdef HAVE_floatunstidf2
2743 if (HAVE_floatunstidf2)
2744 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2745#endif
2746
b092b471
JW
2747#ifdef HAVE_floatunsqixf2
2748 if (HAVE_floatunsqixf2)
2749 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2750#endif
2751#ifdef HAVE_floatunshixf2
2752 if (HAVE_floatunshixf2)
2753 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2754#endif
2755#ifdef HAVE_floatunssixf2
2756 if (HAVE_floatunssixf2)
2757 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2758#endif
2759#ifdef HAVE_floatunsdixf2
2760 if (HAVE_floatunsdixf2)
2761 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2762#endif
2763#ifdef HAVE_floatunstixf2
2764 if (HAVE_floatunstixf2)
2765 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2766#endif
2767
77c9c6c2
RK
2768#ifdef HAVE_floatunsqitf2
2769 if (HAVE_floatunsqitf2)
2770 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2771#endif
2772#ifdef HAVE_floatunshitf2
2773 if (HAVE_floatunshitf2)
2774 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2775#endif
2776#ifdef HAVE_floatunssitf2
2777 if (HAVE_floatunssitf2)
2778 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2779#endif
2780#ifdef HAVE_floatunsditf2
2781 if (HAVE_floatunsditf2)
2782 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2783#endif
2784#ifdef HAVE_floatunstitf2
2785 if (HAVE_floatunstitf2)
2786 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2787#endif
2788}
2789\f
2790/* Generate code to convert FROM to floating point
34e56753 2791 and store in TO. FROM must be fixed point and not VOIDmode.
77c9c6c2
RK
2792 UNSIGNEDP nonzero means regard FROM as unsigned.
2793 Normally this is done by correcting the final value
2794 if it is negative. */
2795
2796void
2797expand_float (to, from, unsignedp)
2798 rtx to, from;
2799 int unsignedp;
2800{
2801 enum insn_code icode;
2802 register rtx target = to;
2803 enum machine_mode fmode, imode;
2804
34e56753
RS
2805 /* Crash now, because we won't be able to decide which mode to use. */
2806 if (GET_MODE (from) == VOIDmode)
2807 abort ();
2808
77c9c6c2
RK
2809 /* Look for an insn to do the conversion. Do it in the specified
2810 modes if possible; otherwise convert either input, output or both to
2811 wider mode. If the integer mode is wider than the mode of FROM,
2812 we can do the conversion signed even if the input is unsigned. */
2813
2814 for (imode = GET_MODE (from); imode != VOIDmode;
2815 imode = GET_MODE_WIDER_MODE (imode))
2816 for (fmode = GET_MODE (to); fmode != VOIDmode;
2817 fmode = GET_MODE_WIDER_MODE (fmode))
2818 {
2819 int doing_unsigned = unsignedp;
2820
2821 icode = can_float_p (fmode, imode, unsignedp);
2822 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2823 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2824
2825 if (icode != CODE_FOR_nothing)
2826 {
2827 to = protect_from_queue (to, 1);
06e40b26 2828 from = protect_from_queue (from, 0);
77c9c6c2
RK
2829
2830 if (imode != GET_MODE (from))
2831 from = convert_to_mode (imode, from, unsignedp);
77c9c6c2
RK
2832
2833 if (fmode != GET_MODE (to))
2834 target = gen_reg_rtx (fmode);
2835
2836 emit_unop_insn (icode, target, from,
2837 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2838
2839 if (target != to)
2840 convert_move (to, target, 0);
2841 return;
2842 }
2843 }
2844
2845#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2846
2847 /* Unsigned integer, and no way to convert directly.
2848 Convert as signed, then conditionally adjust the result. */
2849 if (unsignedp)
2850 {
2851 rtx label = gen_label_rtx ();
2852 rtx temp;
2853 REAL_VALUE_TYPE offset;
2854
2855 emit_queue ();
2856
2857 to = protect_from_queue (to, 1);
2858 from = protect_from_queue (from, 0);
2859
2860 if (flag_force_mem)
2861 from = force_not_mem (from);
2862
2863 /* If we are about to do some arithmetic to correct for an
2864 unsigned operand, do it in a pseudo-register. */
2865
2866 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2867 target = gen_reg_rtx (GET_MODE (to));
2868
2869 /* Convert as signed integer to floating. */
2870 expand_float (target, from, 0);
2871
2872 /* If FROM is negative (and therefore TO is negative),
2873 correct its value by 2**bitwidth. */
2874
2875 do_pending_stack_adjust ();
b1ec3c92 2876 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
77c9c6c2
RK
2877 emit_jump_insn (gen_bge (label));
2878 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2879 Rather than setting up a dconst_dot_5, let's hope SCO
2880 fixes the bug. */
2881 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2882 temp = expand_binop (GET_MODE (to), add_optab, target,
2883 immed_real_const_1 (offset, GET_MODE (to)),
2884 target, 0, OPTAB_LIB_WIDEN);
2885 if (temp != target)
2886 emit_move_insn (target, temp);
2887 do_pending_stack_adjust ();
2888 emit_label (label);
2889 }
2890 else
2891#endif
2892
b092b471
JW
2893 /* No hardware instruction available; call a library rotine to convert from
2894 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
77c9c6c2 2895 {
6bce1b78 2896 rtx libfcn;
77c9c6c2
RK
2897 rtx insns;
2898
2899 to = protect_from_queue (to, 1);
06e40b26 2900 from = protect_from_queue (from, 0);
77c9c6c2
RK
2901
2902 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2903 from = convert_to_mode (SImode, from, unsignedp);
77c9c6c2
RK
2904
2905 if (flag_force_mem)
2906 from = force_not_mem (from);
2907
2908 if (GET_MODE (to) == SFmode)
2909 {
2910 if (GET_MODE (from) == SImode)
6bce1b78 2911 libfcn = floatsisf_libfunc;
77c9c6c2 2912 else if (GET_MODE (from) == DImode)
6bce1b78 2913 libfcn = floatdisf_libfunc;
b092b471
JW
2914 else if (GET_MODE (from) == TImode)
2915 libfcn = floattisf_libfunc;
77c9c6c2
RK
2916 else
2917 abort ();
2918 }
2919 else if (GET_MODE (to) == DFmode)
2920 {
2921 if (GET_MODE (from) == SImode)
6bce1b78 2922 libfcn = floatsidf_libfunc;
77c9c6c2 2923 else if (GET_MODE (from) == DImode)
6bce1b78 2924 libfcn = floatdidf_libfunc;
b092b471
JW
2925 else if (GET_MODE (from) == TImode)
2926 libfcn = floattidf_libfunc;
2927 else
2928 abort ();
2929 }
2930 else if (GET_MODE (to) == XFmode)
2931 {
2932 if (GET_MODE (from) == SImode)
2933 libfcn = floatsixf_libfunc;
2934 else if (GET_MODE (from) == DImode)
2935 libfcn = floatdixf_libfunc;
2936 else if (GET_MODE (from) == TImode)
2937 libfcn = floattixf_libfunc;
2938 else
2939 abort ();
2940 }
2941 else if (GET_MODE (to) == TFmode)
2942 {
2943 if (GET_MODE (from) == SImode)
2944 libfcn = floatsitf_libfunc;
2945 else if (GET_MODE (from) == DImode)
2946 libfcn = floatditf_libfunc;
2947 else if (GET_MODE (from) == TImode)
2948 libfcn = floattitf_libfunc;
77c9c6c2
RK
2949 else
2950 abort ();
2951 }
2952 else
2953 abort ();
2954
2955 start_sequence ();
2956
86f8eff3 2957 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
2958 insns = get_insns ();
2959 end_sequence ();
2960
2961 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2962 gen_rtx (FLOAT, GET_MODE (to), from));
2963 }
2964
2965 /* Copy result to requested destination
2966 if we have been computing in a temp location. */
2967
2968 if (target != to)
2969 {
2970 if (GET_MODE (target) == GET_MODE (to))
2971 emit_move_insn (to, target);
2972 else
2973 convert_move (to, target, 0);
2974 }
2975}
2976\f
2977/* expand_fix: generate code to convert FROM to fixed point
2978 and store in TO. FROM must be floating point. */
2979
2980static rtx
2981ftruncify (x)
2982 rtx x;
2983{
2984 rtx temp = gen_reg_rtx (GET_MODE (x));
2985 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2986}
2987
2988void
2989expand_fix (to, from, unsignedp)
2990 register rtx to, from;
2991 int unsignedp;
2992{
2993 enum insn_code icode;
2994 register rtx target = to;
2995 enum machine_mode fmode, imode;
2996 int must_trunc = 0;
6bce1b78 2997 rtx libfcn = 0;
77c9c6c2
RK
2998
2999 /* We first try to find a pair of modes, one real and one integer, at
3000 least as wide as FROM and TO, respectively, in which we can open-code
3001 this conversion. If the integer mode is wider than the mode of TO,
3002 we can do the conversion either signed or unsigned. */
3003
3004 for (imode = GET_MODE (to); imode != VOIDmode;
3005 imode = GET_MODE_WIDER_MODE (imode))
3006 for (fmode = GET_MODE (from); fmode != VOIDmode;
3007 fmode = GET_MODE_WIDER_MODE (fmode))
3008 {
3009 int doing_unsigned = unsignedp;
3010
3011 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3012 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3013 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3014
3015 if (icode != CODE_FOR_nothing)
3016 {
3017 to = protect_from_queue (to, 1);
06e40b26 3018 from = protect_from_queue (from, 0);
77c9c6c2
RK
3019
3020 if (fmode != GET_MODE (from))
3021 from = convert_to_mode (fmode, from, 0);
77c9c6c2
RK
3022
3023 if (must_trunc)
3024 from = ftruncify (from);
3025
3026 if (imode != GET_MODE (to))
3027 target = gen_reg_rtx (imode);
3028
3029 emit_unop_insn (icode, target, from,
3030 doing_unsigned ? UNSIGNED_FIX : FIX);
3031 if (target != to)
3032 convert_move (to, target, unsignedp);
3033 return;
3034 }
3035 }
3036
3037#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3038 /* For an unsigned conversion, there is one more way to do it.
3039 If we have a signed conversion, we generate code that compares
3040 the real value to the largest representable positive number. If if
3041 is smaller, the conversion is done normally. Otherwise, subtract
3042 one plus the highest signed number, convert, and add it back.
3043
3044 We only need to check all real modes, since we know we didn't find
6dc42e49 3045 anything with a wider integer mode. */
77c9c6c2 3046
b1ec3c92 3047 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
77c9c6c2
RK
3048 for (fmode = GET_MODE (from); fmode != VOIDmode;
3049 fmode = GET_MODE_WIDER_MODE (fmode))
3050 /* Make sure we won't lose significant bits doing this. */
3051 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3052 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3053 &must_trunc))
3054 {
3055 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3056 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3057 rtx limit = immed_real_const_1 (offset, fmode);
3058 rtx lab1 = gen_label_rtx ();
3059 rtx lab2 = gen_label_rtx ();
3060 rtx insn;
3061
3062 emit_queue ();
3063 to = protect_from_queue (to, 1);
3064 from = protect_from_queue (from, 0);
3065
3066 if (flag_force_mem)
3067 from = force_not_mem (from);
3068
3069 if (fmode != GET_MODE (from))
3070 from = convert_to_mode (fmode, from, 0);
3071
3072 /* See if we need to do the subtraction. */
3073 do_pending_stack_adjust ();
b1ec3c92 3074 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
77c9c6c2
RK
3075 emit_jump_insn (gen_bge (lab1));
3076
3077 /* If not, do the signed "fix" and branch around fixup code. */
3078 expand_fix (to, from, 0);
3079 emit_jump_insn (gen_jump (lab2));
3080 emit_barrier ();
3081
3082 /* Otherwise, subtract 2**(N-1), convert to signed number,
3083 then add 2**(N-1). Do the addition using XOR since this
3084 will often generate better code. */
3085 emit_label (lab1);
3086 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
b1ec3c92 3087 NULL_RTX, 0, OPTAB_LIB_WIDEN);
77c9c6c2
RK
3088 expand_fix (to, target, 0);
3089 target = expand_binop (GET_MODE (to), xor_optab, to,
b1ec3c92 3090 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
77c9c6c2
RK
3091 to, 1, OPTAB_LIB_WIDEN);
3092
3093 if (target != to)
3094 emit_move_insn (to, target);
3095
3096 emit_label (lab2);
3097
3098 /* Make a place for a REG_NOTE and add it. */
3099 insn = emit_move_insn (to, to);
3100 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3101 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3102 from), REG_NOTES (insn));
3103
3104 return;
3105 }
3106#endif
3107
3108 /* We can't do it with an insn, so use a library call. But first ensure
3109 that the mode of TO is at least as wide as SImode, since those are the
3110 only library calls we know about. */
3111
3112 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3113 {
3114 target = gen_reg_rtx (SImode);
3115
3116 expand_fix (target, from, unsignedp);
3117 }
3118 else if (GET_MODE (from) == SFmode)
3119 {
3120 if (GET_MODE (to) == SImode)
6bce1b78 3121 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
77c9c6c2 3122 else if (GET_MODE (to) == DImode)
6bce1b78 3123 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
b092b471
JW
3124 else if (GET_MODE (to) == TImode)
3125 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
77c9c6c2
RK
3126 else
3127 abort ();
3128 }
3129 else if (GET_MODE (from) == DFmode)
3130 {
3131 if (GET_MODE (to) == SImode)
6bce1b78 3132 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
77c9c6c2 3133 else if (GET_MODE (to) == DImode)
6bce1b78 3134 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
b092b471
JW
3135 else if (GET_MODE (to) == TImode)
3136 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3137 else
3138 abort ();
3139 }
3140 else if (GET_MODE (from) == XFmode)
3141 {
3142 if (GET_MODE (to) == SImode)
3143 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3144 else if (GET_MODE (to) == DImode)
3145 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3146 else if (GET_MODE (to) == TImode)
3147 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3148 else
3149 abort ();
3150 }
3151 else if (GET_MODE (from) == TFmode)
3152 {
3153 if (GET_MODE (to) == SImode)
3154 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3155 else if (GET_MODE (to) == DImode)
3156 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3157 else if (GET_MODE (to) == TImode)
3158 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
77c9c6c2
RK
3159 else
3160 abort ();
3161 }
3162 else
3163 abort ();
3164
6bce1b78 3165 if (libfcn)
77c9c6c2
RK
3166 {
3167 rtx insns;
3168
3169 to = protect_from_queue (to, 1);
3170 from = protect_from_queue (from, 0);
3171
3172 if (flag_force_mem)
3173 from = force_not_mem (from);
3174
3175 start_sequence ();
3176
86f8eff3 3177 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
3178 insns = get_insns ();
3179 end_sequence ();
3180
3181 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3182 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3183 GET_MODE (to), from));
3184 }
3185
3186 if (GET_MODE (to) == GET_MODE (target))
3187 emit_move_insn (to, target);
3188 else
3189 convert_move (to, target, 0);
3190}
3191\f
3192static optab
3193init_optab (code)
3194 enum rtx_code code;
3195{
3196 int i;
3197 optab op = (optab) xmalloc (sizeof (struct optab));
3198 op->code = code;
3199 for (i = 0; i < NUM_MACHINE_MODES; i++)
3200 {
3201 op->handlers[i].insn_code = CODE_FOR_nothing;
3202 op->handlers[i].libfunc = 0;
3203 }
3204 return op;
3205}
3206
b092b471
JW
3207/* Initialize the libfunc fields of an entire group of entries in some
3208 optab. Each entry is set equal to a string consisting of a leading
3209 pair of underscores followed by a generic operation name followed by
3210 a mode name (downshifted to lower case) followed by a single character
3211 representing the number of operands for the given operation (which is
3212 usually one of the characters '2', '3', or '4').
3213
3214 OPTABLE is the table in which libfunc fields are to be initialized.
3215 FIRST_MODE is the first machine mode index in the given optab to
3216 initialize.
3217 LAST_MODE is the last machine mode index in the given optab to
3218 initialize.
3219 OPNAME is the generic (string) name of the operation.
3220 SUFFIX is the character which specifies the number of operands for
3221 the given generic operation.
3222*/
3223
3224static void
3225init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3226 register optab optable;
3227 register char *opname;
3228 register enum machine_mode first_mode;
3229 register enum machine_mode last_mode;
3230 register char suffix;
3231{
3232 register enum machine_mode mode;
3233 register unsigned opname_len = strlen (opname);
3234
3235 for (mode = first_mode; mode <= last_mode; mode++)
3236 {
3237 register char *mname = mode_name[(int) mode];
3238 register unsigned mname_len = strlen (mname);
3239 register char *libfunc_name
3240 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3241 register char *p;
3242 register char *q;
3243
3244 p = libfunc_name;
3245 *p++ = '_';
3246 *p++ = '_';
3247 for (q = opname; *q; )
3248 *p++ = *q++;
3249 for (q = mname; *q; q++)
3250 *p++ = tolower (*q);
3251 *p++ = suffix;
3252 *p++ = '\0';
3253 optable->handlers[(int) mode].libfunc
3254 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3255 }
3256}
3257
3258/* Initialize the libfunc fields of an entire group of entries in some
3259 optab which correspond to all integer mode operations. The parameters
3260 have the same meaning as similarly named ones for the `init_libfuncs'
3261 routine. (See above). */
3262
3263static void
3264init_integral_libfuncs (optable, opname, suffix)
3265 register optab optable;
3266 register char *opname;
3267 register char suffix;
3268{
3269 init_libfuncs (optable, SImode, TImode, opname, suffix);
3270}
3271
3272/* Initialize the libfunc fields of an entire group of entries in some
3273 optab which correspond to all real mode operations. The parameters
3274 have the same meaning as similarly named ones for the `init_libfuncs'
3275 routine. (See above). */
3276
3277static void
3278init_floating_libfuncs (optable, opname, suffix)
3279 register optab optable;
3280 register char *opname;
3281 register char suffix;
3282{
3283 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3284}
3285
77c9c6c2
RK
3286/* Call this once to initialize the contents of the optabs
3287 appropriately for the current target machine. */
3288
3289void
3290init_optabs ()
3291{
3292 int i;
3293
3294 init_fixtab ();
3295 init_floattab ();
3296 init_extends ();
3297
3298 add_optab = init_optab (PLUS);
3299 sub_optab = init_optab (MINUS);
3300 smul_optab = init_optab (MULT);
3301 smul_widen_optab = init_optab (UNKNOWN);
3302 umul_widen_optab = init_optab (UNKNOWN);
3303 sdiv_optab = init_optab (DIV);
3304 sdivmod_optab = init_optab (UNKNOWN);
3305 udiv_optab = init_optab (UDIV);
3306 udivmod_optab = init_optab (UNKNOWN);
3307 smod_optab = init_optab (MOD);
3308 umod_optab = init_optab (UMOD);
3309 flodiv_optab = init_optab (DIV);
3310 ftrunc_optab = init_optab (UNKNOWN);
3311 and_optab = init_optab (AND);
3312 ior_optab = init_optab (IOR);
3313 xor_optab = init_optab (XOR);
3314 ashl_optab = init_optab (ASHIFT);
3315 ashr_optab = init_optab (ASHIFTRT);
3316 lshl_optab = init_optab (LSHIFT);
3317 lshr_optab = init_optab (LSHIFTRT);
3318 rotl_optab = init_optab (ROTATE);
3319 rotr_optab = init_optab (ROTATERT);
3320 smin_optab = init_optab (SMIN);
3321 smax_optab = init_optab (SMAX);
3322 umin_optab = init_optab (UMIN);
3323 umax_optab = init_optab (UMAX);
3324 mov_optab = init_optab (UNKNOWN);
3325 movstrict_optab = init_optab (UNKNOWN);
3326 cmp_optab = init_optab (UNKNOWN);
3327 ucmp_optab = init_optab (UNKNOWN);
3328 tst_optab = init_optab (UNKNOWN);
3329 neg_optab = init_optab (NEG);
3330 abs_optab = init_optab (ABS);
3331 one_cmpl_optab = init_optab (NOT);
3332 ffs_optab = init_optab (FFS);
d45cf215 3333 sqrt_optab = init_optab (SQRT);
19c3fc24 3334 strlen_optab = init_optab (UNKNOWN);
77c9c6c2
RK
3335
3336#ifdef HAVE_addqi3
3337 if (HAVE_addqi3)
3338 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3339#endif
3340#ifdef HAVE_addhi3
3341 if (HAVE_addhi3)
3342 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3343#endif
3344#ifdef HAVE_addpsi3
3345 if (HAVE_addpsi3)
3346 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3347#endif
3348#ifdef HAVE_addsi3
3349 if (HAVE_addsi3)
3350 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3351#endif
3352#ifdef HAVE_adddi3
3353 if (HAVE_adddi3)
3354 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3355#endif
3356#ifdef HAVE_addti3
3357 if (HAVE_addti3)
3358 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3359#endif
3360#ifdef HAVE_addsf3
3361 if (HAVE_addsf3)
3362 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3363#endif
3364#ifdef HAVE_adddf3
3365 if (HAVE_adddf3)
3366 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3367#endif
b092b471
JW
3368#ifdef HAVE_addxf3
3369 if (HAVE_addxf3)
3370 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3371#endif
77c9c6c2
RK
3372#ifdef HAVE_addtf3
3373 if (HAVE_addtf3)
3374 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3375#endif
b092b471
JW
3376 init_integral_libfuncs (add_optab, "add", '3');
3377 init_floating_libfuncs (add_optab, "add", '3');
77c9c6c2
RK
3378
3379#ifdef HAVE_subqi3
3380 if (HAVE_subqi3)
3381 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3382#endif
3383#ifdef HAVE_subhi3
3384 if (HAVE_subhi3)
3385 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3386#endif
3387#ifdef HAVE_subpsi3
3388 if (HAVE_subpsi3)
3389 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3390#endif
3391#ifdef HAVE_subsi3
3392 if (HAVE_subsi3)
3393 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3394#endif
3395#ifdef HAVE_subdi3
3396 if (HAVE_subdi3)
3397 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3398#endif
3399#ifdef HAVE_subti3
3400 if (HAVE_subti3)
ded40dfe 3401 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
77c9c6c2
RK
3402#endif
3403#ifdef HAVE_subsf3
3404 if (HAVE_subsf3)
3405 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3406#endif
3407#ifdef HAVE_subdf3
3408 if (HAVE_subdf3)
3409 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3410#endif
b092b471
JW
3411#ifdef HAVE_subxf3
3412 if (HAVE_subxf3)
3413 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3414#endif
77c9c6c2
RK
3415#ifdef HAVE_subtf3
3416 if (HAVE_subtf3)
3417 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3418#endif
b092b471
JW
3419 init_integral_libfuncs (sub_optab, "sub", '3');
3420 init_floating_libfuncs (sub_optab, "sub", '3');
77c9c6c2
RK
3421
3422#ifdef HAVE_mulqi3
3423 if (HAVE_mulqi3)
3424 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3425#endif
3426#ifdef HAVE_mulhi3
3427 if (HAVE_mulhi3)
3428 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3429#endif
3430#ifdef HAVE_mulpsi3
3431 if (HAVE_mulpsi3)
3432 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3433#endif
3434#ifdef HAVE_mulsi3
3435 if (HAVE_mulsi3)
3436 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3437#endif
3438#ifdef HAVE_muldi3
3439 if (HAVE_muldi3)
3440 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3441#endif
3442#ifdef HAVE_multi3
3443 if (HAVE_multi3)
3444 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3445#endif
3446#ifdef HAVE_mulsf3
3447 if (HAVE_mulsf3)
3448 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3449#endif
3450#ifdef HAVE_muldf3
3451 if (HAVE_muldf3)
3452 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3453#endif
b092b471
JW
3454#ifdef HAVE_mulxf3
3455 if (HAVE_mulxf3)
3456 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3457#endif
77c9c6c2
RK
3458#ifdef HAVE_multf3
3459 if (HAVE_multf3)
3460 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3461#endif
b092b471
JW
3462 init_integral_libfuncs (smul_optab, "mul", '3');
3463 init_floating_libfuncs (smul_optab, "mul", '3');
77c9c6c2
RK
3464
3465#ifdef MULSI3_LIBCALL
3466 smul_optab->handlers[(int) SImode].libfunc
3467 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
77c9c6c2
RK
3468#endif
3469#ifdef MULDI3_LIBCALL
3470 smul_optab->handlers[(int) DImode].libfunc
3471 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
77c9c6c2 3472#endif
b092b471
JW
3473#ifdef MULTI3_LIBCALL
3474 smul_optab->handlers[(int) TImode].libfunc
3475 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3476#endif
77c9c6c2
RK
3477
3478#ifdef HAVE_mulqihi3
3479 if (HAVE_mulqihi3)
3480 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3481#endif
3482#ifdef HAVE_mulhisi3
3483 if (HAVE_mulhisi3)
3484 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3485#endif
3486#ifdef HAVE_mulsidi3
3487 if (HAVE_mulsidi3)
3488 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3489#endif
3490#ifdef HAVE_mulditi3
3491 if (HAVE_mulditi3)
3492 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3493#endif
3494
3495#ifdef HAVE_umulqihi3
3496 if (HAVE_umulqihi3)
3497 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3498#endif
3499#ifdef HAVE_umulhisi3
3500 if (HAVE_umulhisi3)
3501 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3502#endif
3503#ifdef HAVE_umulsidi3
3504 if (HAVE_umulsidi3)
3505 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3506#endif
3507#ifdef HAVE_umulditi3
3508 if (HAVE_umulditi3)
3509 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3510#endif
3511
3512#ifdef HAVE_divqi3
3513 if (HAVE_divqi3)
3514 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3515#endif
3516#ifdef HAVE_divhi3
3517 if (HAVE_divhi3)
3518 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3519#endif
3520#ifdef HAVE_divpsi3
3521 if (HAVE_divpsi3)
3522 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3523#endif
3524#ifdef HAVE_divsi3
3525 if (HAVE_divsi3)
3526 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3527#endif
3528#ifdef HAVE_divdi3
3529 if (HAVE_divdi3)
3530 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3531#endif
3532#ifdef HAVE_divti3
3533 if (HAVE_divti3)
3534 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3535#endif
b092b471 3536 init_integral_libfuncs (sdiv_optab, "div", '3');
77c9c6c2
RK
3537
3538#ifdef DIVSI3_LIBCALL
3539 sdiv_optab->handlers[(int) SImode].libfunc
3540 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
77c9c6c2
RK
3541#endif
3542#ifdef DIVDI3_LIBCALL
3543 sdiv_optab->handlers[(int) DImode].libfunc
3544 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
b092b471
JW
3545#endif
3546#ifdef DIVTI3_LIBCALL
3547 sdiv_optab->handlers[(int) TImode].libfunc
3548 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
77c9c6c2
RK
3549#endif
3550
3551#ifdef HAVE_udivqi3
3552 if (HAVE_udivqi3)
3553 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3554#endif
3555#ifdef HAVE_udivhi3
3556 if (HAVE_udivhi3)
3557 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3558#endif
3559#ifdef HAVE_udivpsi3
3560 if (HAVE_udivpsi3)
3561 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3562#endif
3563#ifdef HAVE_udivsi3
3564 if (HAVE_udivsi3)
3565 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3566#endif
3567#ifdef HAVE_udivdi3
3568 if (HAVE_udivdi3)
3569 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3570#endif
3571#ifdef HAVE_udivti3
3572 if (HAVE_udivti3)
3573 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3574#endif
b092b471 3575 init_integral_libfuncs (udiv_optab, "udiv", '3');
77c9c6c2
RK
3576
3577#ifdef UDIVSI3_LIBCALL
3578 udiv_optab->handlers[(int) SImode].libfunc
3579 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
77c9c6c2
RK
3580#endif
3581#ifdef UDIVDI3_LIBCALL
3582 udiv_optab->handlers[(int) DImode].libfunc
3583 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
b092b471
JW
3584#endif
3585#ifdef UDIVTI3_LIBCALL
3586 udiv_optab->handlers[(int) TImode].libfunc
3587 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
77c9c6c2
RK
3588#endif
3589
3590#ifdef HAVE_divmodqi4
3591 if (HAVE_divmodqi4)
3592 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3593#endif
3594#ifdef HAVE_divmodhi4
3595 if (HAVE_divmodhi4)
3596 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3597#endif
3598#ifdef HAVE_divmodsi4
3599 if (HAVE_divmodsi4)
3600 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3601#endif
3602#ifdef HAVE_divmoddi4
3603 if (HAVE_divmoddi4)
3604 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3605#endif
3606#ifdef HAVE_divmodti4
3607 if (HAVE_divmodti4)
3608 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3609#endif
b092b471 3610 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
77c9c6c2
RK
3611
3612#ifdef HAVE_udivmodqi4
3613 if (HAVE_udivmodqi4)
3614 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3615#endif
3616#ifdef HAVE_udivmodhi4
3617 if (HAVE_udivmodhi4)
3618 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3619#endif
3620#ifdef HAVE_udivmodsi4
3621 if (HAVE_udivmodsi4)
3622 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3623#endif
3624#ifdef HAVE_udivmoddi4
3625 if (HAVE_udivmoddi4)
3626 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3627#endif
3628#ifdef HAVE_udivmodti4
3629 if (HAVE_udivmodti4)
3630 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3631#endif
b092b471 3632 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
77c9c6c2
RK
3633
3634#ifdef HAVE_modqi3
3635 if (HAVE_modqi3)
3636 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3637#endif
3638#ifdef HAVE_modhi3
3639 if (HAVE_modhi3)
3640 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3641#endif
3642#ifdef HAVE_modpsi3
3643 if (HAVE_modpsi3)
3644 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3645#endif
3646#ifdef HAVE_modsi3
3647 if (HAVE_modsi3)
3648 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3649#endif
3650#ifdef HAVE_moddi3
3651 if (HAVE_moddi3)
3652 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3653#endif
3654#ifdef HAVE_modti3
3655 if (HAVE_modti3)
3656 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3657#endif
b092b471 3658 init_integral_libfuncs (smod_optab, "mod", '3');
77c9c6c2
RK
3659
3660#ifdef MODSI3_LIBCALL
3661 smod_optab->handlers[(int) SImode].libfunc
3662 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
77c9c6c2
RK
3663#endif
3664#ifdef MODDI3_LIBCALL
3665 smod_optab->handlers[(int) DImode].libfunc
3666 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
b092b471
JW
3667#endif
3668#ifdef MODTI3_LIBCALL
3669 smod_optab->handlers[(int) TImode].libfunc
3670 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
77c9c6c2
RK
3671#endif
3672
3673#ifdef HAVE_umodqi3
3674 if (HAVE_umodqi3)
3675 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3676#endif
3677#ifdef HAVE_umodhi3
3678 if (HAVE_umodhi3)
3679 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3680#endif
3681#ifdef HAVE_umodpsi3
3682 if (HAVE_umodpsi3)
3683 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3684#endif
3685#ifdef HAVE_umodsi3
3686 if (HAVE_umodsi3)
3687 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3688#endif
3689#ifdef HAVE_umoddi3
3690 if (HAVE_umoddi3)
3691 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3692#endif
3693#ifdef HAVE_umodti3
3694 if (HAVE_umodti3)
3695 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3696#endif
b092b471 3697 init_integral_libfuncs (umod_optab, "umod", '3');
77c9c6c2
RK
3698
3699#ifdef UMODSI3_LIBCALL
3700 umod_optab->handlers[(int) SImode].libfunc
3701 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
77c9c6c2
RK
3702#endif
3703#ifdef UMODDI3_LIBCALL
3704 umod_optab->handlers[(int) DImode].libfunc
3705 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
b092b471
JW
3706#endif
3707#ifdef UMODTI3_LIBCALL
3708 umod_optab->handlers[(int) TImode].libfunc
3709 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
77c9c6c2
RK
3710#endif
3711
3712#ifdef HAVE_divsf3
3713 if (HAVE_divsf3)
3714 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3715#endif
3716#ifdef HAVE_divdf3
3717 if (HAVE_divdf3)
3718 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3719#endif
b092b471
JW
3720#ifdef HAVE_divxf3
3721 if (HAVE_divxf3)
3722 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3723#endif
77c9c6c2
RK
3724#ifdef HAVE_divtf3
3725 if (HAVE_divtf3)
3726 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3727#endif
b092b471 3728 init_floating_libfuncs (flodiv_optab, "div", '3');
77c9c6c2
RK
3729
3730#ifdef HAVE_ftruncsf2
3731 if (HAVE_ftruncsf2)
3732 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3733#endif
3734#ifdef HAVE_ftruncdf2
3735 if (HAVE_ftruncdf2)
3736 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3737#endif
b092b471
JW
3738#ifdef HAVE_ftruncxf2
3739 if (HAVE_ftruncxf2)
3740 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3741#endif
77c9c6c2
RK
3742#ifdef HAVE_ftrunctf2
3743 if (HAVE_ftrunctf2)
3744 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3745#endif
b092b471 3746 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
77c9c6c2
RK
3747
3748#ifdef HAVE_andqi3
3749 if (HAVE_andqi3)
3750 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3751#endif
3752#ifdef HAVE_andhi3
3753 if (HAVE_andhi3)
3754 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3755#endif
3756#ifdef HAVE_andpsi3
3757 if (HAVE_andpsi3)
3758 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3759#endif
3760#ifdef HAVE_andsi3
3761 if (HAVE_andsi3)
3762 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3763#endif
3764#ifdef HAVE_anddi3
3765 if (HAVE_anddi3)
3766 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3767#endif
3768#ifdef HAVE_andti3
3769 if (HAVE_andti3)
3770 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3771#endif
b092b471 3772 init_integral_libfuncs (and_optab, "and", '3');
77c9c6c2
RK
3773
3774#ifdef HAVE_iorqi3
3775 if (HAVE_iorqi3)
3776 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3777#endif
3778#ifdef HAVE_iorhi3
3779 if (HAVE_iorhi3)
3780 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3781#endif
3782#ifdef HAVE_iorpsi3
3783 if (HAVE_iorpsi3)
3784 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3785#endif
3786#ifdef HAVE_iorsi3
3787 if (HAVE_iorsi3)
3788 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3789#endif
3790#ifdef HAVE_iordi3
3791 if (HAVE_iordi3)
3792 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3793#endif
3794#ifdef HAVE_iorti3
3795 if (HAVE_iorti3)
3796 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3797#endif
b092b471 3798 init_integral_libfuncs (ior_optab, "ior", '3');
77c9c6c2
RK
3799
3800#ifdef HAVE_xorqi3
3801 if (HAVE_xorqi3)
3802 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3803#endif
3804#ifdef HAVE_xorhi3
3805 if (HAVE_xorhi3)
3806 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3807#endif
3808#ifdef HAVE_xorpsi3
3809 if (HAVE_xorpsi3)
3810 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3811#endif
3812#ifdef HAVE_xorsi3
3813 if (HAVE_xorsi3)
3814 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3815#endif
3816#ifdef HAVE_xordi3
3817 if (HAVE_xordi3)
3818 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3819#endif
3820#ifdef HAVE_xorti3
3821 if (HAVE_xorti3)
3822 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3823#endif
b092b471 3824 init_integral_libfuncs (xor_optab, "xor", '3');
77c9c6c2
RK
3825
3826#ifdef HAVE_ashlqi3
3827 if (HAVE_ashlqi3)
3828 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3829#endif
3830#ifdef HAVE_ashlhi3
3831 if (HAVE_ashlhi3)
3832 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3833#endif
3834#ifdef HAVE_ashlpsi3
3835 if (HAVE_ashlpsi3)
3836 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3837#endif
3838#ifdef HAVE_ashlsi3
3839 if (HAVE_ashlsi3)
3840 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3841#endif
3842#ifdef HAVE_ashldi3
3843 if (HAVE_ashldi3)
3844 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3845#endif
3846#ifdef HAVE_ashlti3
3847 if (HAVE_ashlti3)
3848 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3849#endif
b092b471 3850 init_integral_libfuncs (ashl_optab, "ashl", '3');
77c9c6c2
RK
3851
3852#ifdef HAVE_ashrqi3
3853 if (HAVE_ashrqi3)
3854 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3855#endif
3856#ifdef HAVE_ashrhi3
3857 if (HAVE_ashrhi3)
3858 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3859#endif
3860#ifdef HAVE_ashrpsi3
3861 if (HAVE_ashrpsi3)
3862 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3863#endif
3864#ifdef HAVE_ashrsi3
3865 if (HAVE_ashrsi3)
3866 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3867#endif
3868#ifdef HAVE_ashrdi3
3869 if (HAVE_ashrdi3)
3870 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3871#endif
3872#ifdef HAVE_ashrti3
3873 if (HAVE_ashrti3)
3874 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3875#endif
b092b471 3876 init_integral_libfuncs (ashr_optab, "ashr", '3');
77c9c6c2
RK
3877
3878#ifdef HAVE_lshlqi3
3879 if (HAVE_lshlqi3)
3880 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3881#endif
3882#ifdef HAVE_lshlhi3
3883 if (HAVE_lshlhi3)
3884 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3885#endif
3886#ifdef HAVE_lshlpsi3
3887 if (HAVE_lshlpsi3)
3888 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3889#endif
3890#ifdef HAVE_lshlsi3
3891 if (HAVE_lshlsi3)
3892 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3893#endif
3894#ifdef HAVE_lshldi3
3895 if (HAVE_lshldi3)
3896 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3897#endif
3898#ifdef HAVE_lshlti3
3899 if (HAVE_lshlti3)
3900 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3901#endif
b092b471 3902 init_integral_libfuncs (lshl_optab, "lshl", '3');
77c9c6c2
RK
3903
3904#ifdef HAVE_lshrqi3
3905 if (HAVE_lshrqi3)
3906 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3907#endif
3908#ifdef HAVE_lshrhi3
3909 if (HAVE_lshrhi3)
3910 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3911#endif
3912#ifdef HAVE_lshrpsi3
3913 if (HAVE_lshrpsi3)
3914 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3915#endif
3916#ifdef HAVE_lshrsi3
3917 if (HAVE_lshrsi3)
3918 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3919#endif
3920#ifdef HAVE_lshrdi3
3921 if (HAVE_lshrdi3)
3922 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3923#endif
3924#ifdef HAVE_lshrti3
3925 if (HAVE_lshrti3)
3926 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3927#endif
b092b471 3928 init_integral_libfuncs (lshr_optab, "lshr", '3');
77c9c6c2
RK
3929
3930#ifdef HAVE_rotlqi3
3931 if (HAVE_rotlqi3)
3932 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3933#endif
3934#ifdef HAVE_rotlhi3
3935 if (HAVE_rotlhi3)
3936 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3937#endif
3938#ifdef HAVE_rotlpsi3
3939 if (HAVE_rotlpsi3)
3940 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3941#endif
3942#ifdef HAVE_rotlsi3
3943 if (HAVE_rotlsi3)
3944 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3945#endif
3946#ifdef HAVE_rotldi3
3947 if (HAVE_rotldi3)
3948 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3949#endif
3950#ifdef HAVE_rotlti3
3951 if (HAVE_rotlti3)
3952 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3953#endif
b092b471 3954 init_integral_libfuncs (rotl_optab, "rotl", '3');
77c9c6c2
RK
3955
3956#ifdef HAVE_rotrqi3
3957 if (HAVE_rotrqi3)
3958 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3959#endif
3960#ifdef HAVE_rotrhi3
3961 if (HAVE_rotrhi3)
3962 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3963#endif
3964#ifdef HAVE_rotrpsi3
3965 if (HAVE_rotrpsi3)
3966 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3967#endif
3968#ifdef HAVE_rotrsi3
3969 if (HAVE_rotrsi3)
3970 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3971#endif
3972#ifdef HAVE_rotrdi3
3973 if (HAVE_rotrdi3)
3974 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3975#endif
3976#ifdef HAVE_rotrti3
3977 if (HAVE_rotrti3)
3978 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3979#endif
b092b471 3980 init_integral_libfuncs (rotr_optab, "rotr", '3');
77c9c6c2
RK
3981
3982#ifdef HAVE_sminqi3
3983 if (HAVE_sminqi3)
3984 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3985#endif
3986#ifdef HAVE_sminhi3
3987 if (HAVE_sminhi3)
3988 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3989#endif
3990#ifdef HAVE_sminsi3
3991 if (HAVE_sminsi3)
3992 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3993#endif
3994#ifdef HAVE_smindi3
3995 if (HAVE_smindi3)
3996 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3997#endif
3998#ifdef HAVE_sminti3
3999 if (HAVE_sminti3)
4000 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4001#endif
b092b471
JW
4002#ifdef HAVE_minsf3
4003 if (HAVE_minsf3)
4004 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4005#endif
4006#ifdef HAVE_mindf3
4007 if (HAVE_mindf3)
4008 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
77c9c6c2 4009#endif
b092b471
JW
4010#ifdef HAVE_minxf3
4011 if (HAVE_minxf3)
4012 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
77c9c6c2 4013#endif
b092b471
JW
4014#ifdef HAVE_mintf3
4015 if (HAVE_mintf3)
4016 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
77c9c6c2 4017#endif
b092b471
JW
4018 init_integral_libfuncs (smin_optab, "min", '3');
4019 init_floating_libfuncs (smin_optab, "min", '3');
77c9c6c2
RK
4020
4021#ifdef HAVE_smaxqi3
4022 if (HAVE_smaxqi3)
4023 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4024#endif
4025#ifdef HAVE_smaxhi3
4026 if (HAVE_smaxhi3)
4027 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4028#endif
4029#ifdef HAVE_smaxsi3
4030 if (HAVE_smaxsi3)
4031 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4032#endif
4033#ifdef HAVE_smaxdi3
4034 if (HAVE_smaxdi3)
4035 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4036#endif
4037#ifdef HAVE_smaxti3
4038 if (HAVE_smaxti3)
4039 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4040#endif
b092b471
JW
4041#ifdef HAVE_maxsf3
4042 if (HAVE_maxsf3)
4043 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
77c9c6c2 4044#endif
b092b471
JW
4045#ifdef HAVE_maxdf3
4046 if (HAVE_maxdf3)
4047 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
77c9c6c2 4048#endif
b092b471
JW
4049#ifdef HAVE_maxxf3
4050 if (HAVE_maxxf3)
4051 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
77c9c6c2 4052#endif
b092b471
JW
4053#ifdef HAVE_maxtf3
4054 if (HAVE_maxtf3)
4055 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4056#endif
4057 init_integral_libfuncs (smax_optab, "max", '3');
4058 init_floating_libfuncs (smax_optab, "max", '3');
77c9c6c2
RK
4059
4060#ifdef HAVE_uminqi3
4061 if (HAVE_uminqi3)
4062 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4063#endif
4064#ifdef HAVE_uminhi3
4065 if (HAVE_uminhi3)
4066 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4067#endif
4068#ifdef HAVE_uminsi3
4069 if (HAVE_uminsi3)
4070 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4071#endif
4072#ifdef HAVE_umindi3
4073 if (HAVE_umindi3)
4074 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4075#endif
4076#ifdef HAVE_uminti3
4077 if (HAVE_uminti3)
4078 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4079#endif
b092b471 4080 init_integral_libfuncs (umin_optab, "umin", '3');
77c9c6c2
RK
4081
4082#ifdef HAVE_umaxqi3
4083 if (HAVE_umaxqi3)
4084 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4085#endif
4086#ifdef HAVE_umaxhi3
4087 if (HAVE_umaxhi3)
4088 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4089#endif
4090#ifdef HAVE_umaxsi3
4091 if (HAVE_umaxsi3)
4092 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4093#endif
4094#ifdef HAVE_umaxdi3
4095 if (HAVE_umaxdi3)
4096 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4097#endif
4098#ifdef HAVE_umaxti3
4099 if (HAVE_umaxti3)
4100 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4101#endif
b092b471 4102 init_integral_libfuncs (umax_optab, "umax", '3');
77c9c6c2
RK
4103
4104#ifdef HAVE_negqi2
4105 if (HAVE_negqi2)
4106 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4107#endif
4108#ifdef HAVE_neghi2
4109 if (HAVE_neghi2)
4110 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4111#endif
4112#ifdef HAVE_negpsi2
4113 if (HAVE_negpsi2)
4114 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4115#endif
4116#ifdef HAVE_negsi2
4117 if (HAVE_negsi2)
4118 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4119#endif
4120#ifdef HAVE_negdi2
4121 if (HAVE_negdi2)
4122 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4123#endif
4124#ifdef HAVE_negti2
4125 if (HAVE_negti2)
4126 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4127#endif
4128#ifdef HAVE_negsf2
4129 if (HAVE_negsf2)
4130 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4131#endif
4132#ifdef HAVE_negdf2
4133 if (HAVE_negdf2)
4134 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4135#endif
b092b471
JW
4136#ifdef HAVE_negxf2
4137 if (HAVE_negxf2)
4138 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4139#endif
77c9c6c2
RK
4140#ifdef HAVE_negtf2
4141 if (HAVE_negtf2)
4142 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4143#endif
b092b471
JW
4144 init_integral_libfuncs (neg_optab, "neg", '2');
4145 init_floating_libfuncs (neg_optab, "neg", '2');
77c9c6c2
RK
4146
4147#ifdef HAVE_absqi2
4148 if (HAVE_absqi2)
4149 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4150#endif
4151#ifdef HAVE_abshi2
4152 if (HAVE_abshi2)
4153 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4154#endif
4155#ifdef HAVE_abspsi2
4156 if (HAVE_abspsi2)
4157 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4158#endif
4159#ifdef HAVE_abssi2
4160 if (HAVE_abssi2)
4161 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4162#endif
4163#ifdef HAVE_absdi2
4164 if (HAVE_absdi2)
4165 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4166#endif
4167#ifdef HAVE_absti2
4168 if (HAVE_absti2)
4169 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4170#endif
4171#ifdef HAVE_abssf2
4172 if (HAVE_abssf2)
4173 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4174#endif
4175#ifdef HAVE_absdf2
4176 if (HAVE_absdf2)
4177 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4178#endif
b092b471
JW
4179#ifdef HAVE_absxf2
4180 if (HAVE_absxf2)
4181 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4182#endif
77c9c6c2
RK
4183#ifdef HAVE_abstf2
4184 if (HAVE_abstf2)
4185 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4186#endif
4187 /* No library calls here! If there is no abs instruction,
4188 expand_expr will generate a conditional negation. */
4189
d45cf215
RS
4190#ifdef HAVE_sqrtqi2
4191 if (HAVE_sqrtqi2)
4192 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4193#endif
4194#ifdef HAVE_sqrthi2
4195 if (HAVE_sqrthi2)
4196 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4197#endif
4198#ifdef HAVE_sqrtpsi2
4199 if (HAVE_sqrtpsi2)
4200 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4201#endif
4202#ifdef HAVE_sqrtsi2
4203 if (HAVE_sqrtsi2)
4204 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4205#endif
4206#ifdef HAVE_sqrtdi2
4207 if (HAVE_sqrtdi2)
4208 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4209#endif
4210#ifdef HAVE_sqrtti2
4211 if (HAVE_sqrtti2)
4212 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4213#endif
4214#ifdef HAVE_sqrtsf2
4215 if (HAVE_sqrtsf2)
4216 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4217#endif
4218#ifdef HAVE_sqrtdf2
4219 if (HAVE_sqrtdf2)
4220 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4221#endif
4222#ifdef HAVE_sqrttf2
4223 if (HAVE_sqrttf2)
4224 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4225#endif
4226 /* No library calls here! If there is no sqrt instruction expand_builtin
4227 should force the library call. */
4228
19c3fc24
RS
4229#ifdef HAVE_strlenqi
4230 if (HAVE_strlenqi)
4231 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4232#endif
4233#ifdef HAVE_strlenhi
4234 if (HAVE_strlenhi)
4235 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4236#endif
4237#ifdef HAVE_strlenpsi
4238 if (HAVE_strlenpsi)
4239 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4240#endif
4241#ifdef HAVE_strlensi
4242 if (HAVE_strlensi)
4243 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4244#endif
4245#ifdef HAVE_strlendi
4246 if (HAVE_strlendi)
4247 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4248#endif
4249#ifdef HAVE_strlenti
4250 if (HAVE_strlenti)
4251 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4252#endif
4253 /* No library calls here! If there is no strlen instruction expand_builtin
4254 should force the library call. */
4255
77c9c6c2
RK
4256#ifdef HAVE_one_cmplqi2
4257 if (HAVE_one_cmplqi2)
4258 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4259#endif
4260#ifdef HAVE_one_cmplhi2
4261 if (HAVE_one_cmplhi2)
4262 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4263#endif
4264#ifdef HAVE_one_cmplpsi2
4265 if (HAVE_one_cmplpsi2)
4266 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4267#endif
4268#ifdef HAVE_one_cmplsi2
4269 if (HAVE_one_cmplsi2)
4270 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4271#endif
4272#ifdef HAVE_one_cmpldi2
4273 if (HAVE_one_cmpldi2)
4274 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4275#endif
4276#ifdef HAVE_one_cmplti2
4277 if (HAVE_one_cmplti2)
4278 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4279#endif
b092b471 4280 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
77c9c6c2
RK
4281
4282#ifdef HAVE_ffsqi2
4283 if (HAVE_ffsqi2)
4284 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4285#endif
4286#ifdef HAVE_ffshi2
4287 if (HAVE_ffshi2)
4288 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4289#endif
4290#ifdef HAVE_ffspsi2
4291 if (HAVE_ffspsi2)
4292 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4293#endif
4294#ifdef HAVE_ffssi2
4295 if (HAVE_ffssi2)
4296 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4297#endif
4298#ifdef HAVE_ffsdi2
4299 if (HAVE_ffsdi2)
4300 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4301#endif
4302#ifdef HAVE_ffsti2
4303 if (HAVE_ffsti2)
4304 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4305#endif
b092b471 4306 init_integral_libfuncs (ffs_optab, "ffs", '2');
77c9c6c2
RK
4307
4308#ifdef HAVE_movqi
4309 if (HAVE_movqi)
4310 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4311#endif
4312#ifdef HAVE_movhi
4313 if (HAVE_movhi)
4314 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4315#endif
4316#ifdef HAVE_movpsi
4317 if (HAVE_movpsi)
4318 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4319#endif
4320#ifdef HAVE_movsi
4321 if (HAVE_movsi)
4322 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4323#endif
4324#ifdef HAVE_movdi
4325 if (HAVE_movdi)
4326 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4327#endif
4328#ifdef HAVE_movti
4329 if (HAVE_movti)
4330 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4331#endif
4332#ifdef HAVE_movsf
4333 if (HAVE_movsf)
4334 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4335#endif
4336#ifdef HAVE_movdf
4337 if (HAVE_movdf)
4338 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4339#endif
b092b471
JW
4340#ifdef HAVE_movxf
4341 if (HAVE_movxf)
4342 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4343#endif
77c9c6c2
RK
4344#ifdef HAVE_movtf
4345 if (HAVE_movtf)
4346 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4347#endif
4348#ifdef HAVE_movcc
4349 if (HAVE_movcc)
4350 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4351#endif
4352
4353#ifdef EXTRA_CC_MODES
4354 init_mov_optab ();
4355#endif
4356
4357#ifdef HAVE_movstrictqi
4358 if (HAVE_movstrictqi)
4359 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4360#endif
4361#ifdef HAVE_movstricthi
4362 if (HAVE_movstricthi)
4363 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4364#endif
4365#ifdef HAVE_movstrictpsi
4366 if (HAVE_movstrictpsi)
4367 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4368#endif
4369#ifdef HAVE_movstrictsi
4370 if (HAVE_movstrictsi)
4371 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4372#endif
4373#ifdef HAVE_movstrictdi
4374 if (HAVE_movstrictdi)
4375 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4376#endif
4377#ifdef HAVE_movstrictti
4378 if (HAVE_movstrictti)
4379 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4380#endif
4381
4382#ifdef HAVE_cmpqi
4383 if (HAVE_cmpqi)
4384 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4385#endif
4386#ifdef HAVE_cmphi
4387 if (HAVE_cmphi)
4388 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4389#endif
4390#ifdef HAVE_cmppsi
4391 if (HAVE_cmppsi)
4392 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4393#endif
4394#ifdef HAVE_cmpsi
4395 if (HAVE_cmpsi)
4396 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4397#endif
4398#ifdef HAVE_cmpdi
4399 if (HAVE_cmpdi)
4400 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4401#endif
4402#ifdef HAVE_cmpti
4403 if (HAVE_cmpti)
4404 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4405#endif
4406#ifdef HAVE_cmpsf
4407 if (HAVE_cmpsf)
4408 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4409#endif
4410#ifdef HAVE_cmpdf
4411 if (HAVE_cmpdf)
4412 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4413#endif
b092b471
JW
4414#ifdef HAVE_cmpxf
4415 if (HAVE_cmpxf)
4416 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4417#endif
77c9c6c2
RK
4418#ifdef HAVE_cmptf
4419 if (HAVE_cmptf)
4420 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4421#endif
b092b471
JW
4422 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4423 init_integral_libfuncs (cmp_optab, "cmp", '2');
4424 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4425 init_floating_libfuncs (cmp_optab, "cmp", '2');
4426
77c9c6c2
RK
4427#ifdef HAVE_tstqi
4428 if (HAVE_tstqi)
4429 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4430#endif
4431#ifdef HAVE_tsthi
4432 if (HAVE_tsthi)
4433 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4434#endif
4435#ifdef HAVE_tstpsi
4436 if (HAVE_tstpsi)
4437 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4438#endif
4439#ifdef HAVE_tstsi
4440 if (HAVE_tstsi)
4441 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4442#endif
4443#ifdef HAVE_tstdi
4444 if (HAVE_tstdi)
4445 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4446#endif
4447#ifdef HAVE_tstti
4448 if (HAVE_tstti)
4449 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4450#endif
4451#ifdef HAVE_tstsf
4452 if (HAVE_tstsf)
4453 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4454#endif
4455#ifdef HAVE_tstdf
4456 if (HAVE_tstdf)
4457 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4458#endif
b092b471
JW
4459#ifdef HAVE_tstxf
4460 if (HAVE_tstxf)
4461 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4462#endif
77c9c6c2
RK
4463#ifdef HAVE_tsttf
4464 if (HAVE_tsttf)
4465 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4466#endif
77c9c6c2
RK
4467
4468#ifdef HAVE_beq
4469 if (HAVE_beq)
4470 bcc_gen_fctn[(int) EQ] = gen_beq;
4471#endif
4472#ifdef HAVE_bne
4473 if (HAVE_bne)
4474 bcc_gen_fctn[(int) NE] = gen_bne;
4475#endif
4476#ifdef HAVE_bgt
4477 if (HAVE_bgt)
4478 bcc_gen_fctn[(int) GT] = gen_bgt;
4479#endif
4480#ifdef HAVE_bge
4481 if (HAVE_bge)
4482 bcc_gen_fctn[(int) GE] = gen_bge;
4483#endif
4484#ifdef HAVE_bgtu
4485 if (HAVE_bgtu)
4486 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4487#endif
4488#ifdef HAVE_bgeu
4489 if (HAVE_bgeu)
4490 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4491#endif
4492#ifdef HAVE_blt
4493 if (HAVE_blt)
4494 bcc_gen_fctn[(int) LT] = gen_blt;
4495#endif
4496#ifdef HAVE_ble
4497 if (HAVE_ble)
4498 bcc_gen_fctn[(int) LE] = gen_ble;
4499#endif
4500#ifdef HAVE_bltu
4501 if (HAVE_bltu)
4502 bcc_gen_fctn[(int) LTU] = gen_bltu;
4503#endif
4504#ifdef HAVE_bleu
4505 if (HAVE_bleu)
4506 bcc_gen_fctn[(int) LEU] = gen_bleu;
4507#endif
4508
4509 for (i = 0; i < NUM_RTX_CODE; i++)
4510 setcc_gen_code[i] = CODE_FOR_nothing;
4511
4512#ifdef HAVE_seq
4513 if (HAVE_seq)
4514 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4515#endif
4516#ifdef HAVE_sne
4517 if (HAVE_sne)
4518 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4519#endif
4520#ifdef HAVE_sgt
4521 if (HAVE_sgt)
4522 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4523#endif
4524#ifdef HAVE_sge
4525 if (HAVE_sge)
4526 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4527#endif
4528#ifdef HAVE_sgtu
4529 if (HAVE_sgtu)
4530 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4531#endif
4532#ifdef HAVE_sgeu
4533 if (HAVE_sgeu)
4534 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4535#endif
4536#ifdef HAVE_slt
4537 if (HAVE_slt)
4538 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4539#endif
4540#ifdef HAVE_sle
4541 if (HAVE_sle)
4542 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4543#endif
4544#ifdef HAVE_sltu
4545 if (HAVE_sltu)
4546 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4547#endif
4548#ifdef HAVE_sleu
4549 if (HAVE_sleu)
4550 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4551#endif
4552
4553 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
b092b471
JW
4554 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4555 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4556 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4557 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4558
77c9c6c2 4559 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
b092b471
JW
4560 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4561 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4562 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4563 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4564
77c9c6c2
RK
4565 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4566 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4567 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4568 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4569 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4570 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
b092b471 4571
77c9c6c2
RK
4572 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4573 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4574 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4575 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4576 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4577 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
b092b471 4578
77c9c6c2
RK
4579 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4580 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4581 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4582 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4583 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4584 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
b092b471
JW
4585
4586 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4587 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4588 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4589 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4590 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4591 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4592
4593 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4594 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4595 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4596 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4597 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4598 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4599
6bce1b78 4600 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
b092b471
JW
4601 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4602 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4603
6bce1b78 4604 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
b092b471
JW
4605 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4606 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4607
4608 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4609 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4610 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4611
4612 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4613 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4614 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4615
6bce1b78
RK
4616 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4617 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
b092b471
JW
4618 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4619
6bce1b78
RK
4620 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4621 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
b092b471
JW
4622 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4623
4624 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4625 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4626 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4627
4628 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4629 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4630 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4631
6bce1b78
RK
4632 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4633 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
b092b471
JW
4634 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4635
6bce1b78
RK
4636 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4637 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
b092b471
JW
4638 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4639
4640 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4641 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4642 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4643
4644 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4645 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4646 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
77c9c6c2 4647}
7e1966ca
JVA
4648\f
4649#ifdef BROKEN_LDEXP
4650
4651/* SCO 3.2 apparently has a broken ldexp. */
4652
4653double
4654ldexp(x,n)
4655 double x;
4656 int n;
4657{
4658 if (n > 0)
4659 while (n--)
4660 x *= 2;
4661
4662 return x;
4663}
4664#endif /* BROKEN_LDEXP */
This page took 0.523615 seconds and 5 git commands to generate.