]> gcc.gnu.org Git - gcc.git/blame - gcc/optabs.c
*** empty log message ***
[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);
405 return expand_binop (mode, binoptab, op0, op1, 0, unsignedp,
406 methods);
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
457 temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
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 {
714 rtx wordm1 = gen_rtx (CONST_INT, VOIDmode, BITS_PER_WORD - 1);
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,
77c9c6c2
RK
718 0, 1, OPTAB_DIRECT);
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,
77c9c6c2
RK
725 0, 0, OPTAB_DIRECT);
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,
77c9c6c2
RK
733 0, 1, OPTAB_DIRECT);
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,
77c9c6c2
RK
740 0, 0, OPTAB_DIRECT);
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);
34e56753 762 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh, 0,
77c9c6c2
RK
763 0, OPTAB_DIRECT);
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
34e56753 773 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 0,
77c9c6c2
RK
774 0, OPTAB_DIRECT);
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
RK
881
882 temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
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
1155 && ! add_equal_note (pat, temp, unoptab->code, xop0, 0))
1156 {
1157 delete_insns_since (last);
1158 return expand_unop (mode, unoptab, op0, 0, unsignedp);
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
1189 temp = expand_unop (wider_mode, unoptab, xop0, 0, unsignedp);
1190
1191 if (temp)
1192 {
1193 if (class != MODE_INT)
1194 {
1195 if (target == 0)
1196 target = gen_reg_rtx (mode);
1197 convert_move (target, temp, 0);
1198 return target;
1199 }
1200 else
1201 return gen_lowpart (mode, temp);
1202 }
1203 else
1204 delete_insns_since (last);
1205 }
1206 }
1207
77c9c6c2
RK
1208 /* These can be done a word at a time. */
1209 if (unoptab == one_cmpl_optab
1210 && class == MODE_INT
1211 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
34e56753 1212 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2
RK
1213 {
1214 int i;
1215 rtx insns;
1216
1217 if (target == 0 || target == op0)
1218 target = gen_reg_rtx (mode);
1219
1220 start_sequence ();
1221
1222 /* Do the actual arithmetic. */
1223 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1224 {
1225 rtx target_piece = operand_subword (target, i, 1, mode);
34e56753 1226 rtx x = expand_unop (word_mode, unoptab,
77c9c6c2
RK
1227 operand_subword_force (op0, i, mode),
1228 target_piece, unsignedp);
1229 if (target_piece != x)
1230 emit_move_insn (target_piece, x);
1231 }
1232
1233 insns = get_insns ();
1234 end_sequence ();
1235
1236 emit_no_conflict_block (insns, target, op0, 0,
1237 gen_rtx (unoptab->code, mode, op0));
1238 return target;
1239 }
1240
1241 if (unoptab->handlers[(int) mode].libfunc)
1242 {
1243 rtx insns;
1244 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1245
1246 start_sequence ();
1247
1248 /* Pass 1 for NO_QUEUE so we don't lose any increments
1249 if the libcall is cse'd or moved. */
1250 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1251 1, mode, 1, op0, mode);
1252 insns = get_insns ();
1253 end_sequence ();
1254
1255 target = gen_reg_rtx (mode);
1256 emit_libcall_block (insns, target, hard_libcall_value (mode),
1257 gen_rtx (unoptab->code, mode, op0));
1258
1259 return target;
1260 }
1261
1262 /* It can't be done in this mode. Can we do it in a wider mode? */
1263
1264 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1265 {
34e56753 1266 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1267 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1268 {
1269 if ((unoptab->handlers[(int) wider_mode].insn_code
1270 != CODE_FOR_nothing)
1271 || unoptab->handlers[(int) wider_mode].libfunc)
1272 {
34e56753
RS
1273 rtx xop0 = op0;
1274
1275 /* For certain operations, we need not actually extend
1276 the narrow operand, as long as we will truncate the
1277 results to the same narrowness. */
1278
1279 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1280 && class == MODE_INT)
1281 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1282 else
1283 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
77c9c6c2 1284
34e56753
RS
1285 temp = expand_unop (wider_mode, unoptab, xop0, 0, unsignedp);
1286
1287 if (temp)
77c9c6c2 1288 {
34e56753
RS
1289 if (class != MODE_INT)
1290 {
1291 if (target == 0)
1292 target = gen_reg_rtx (mode);
1293 convert_move (target, temp, 0);
1294 return target;
1295 }
1296 else
1297 return gen_lowpart (mode, temp);
77c9c6c2
RK
1298 }
1299 else
34e56753 1300 delete_insns_since (last);
77c9c6c2
RK
1301 }
1302 }
1303 }
1304
1305 return 0;
1306}
1307\f
1308/* Generate an instruction whose insn-code is INSN_CODE,
1309 with two operands: an output TARGET and an input OP0.
1310 TARGET *must* be nonzero, and the output is always stored there.
1311 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1312 the value that is stored into TARGET. */
1313
1314void
1315emit_unop_insn (icode, target, op0, code)
1316 int icode;
1317 rtx target;
1318 rtx op0;
1319 enum rtx_code code;
1320{
1321 register rtx temp;
1322 enum machine_mode mode0 = insn_operand_mode[icode][1];
1323 rtx pat;
1324
1325 temp = target = protect_from_queue (target, 1);
1326
1327 op0 = protect_from_queue (op0, 0);
1328
1329 if (flag_force_mem)
1330 op0 = force_not_mem (op0);
1331
1332 /* Now, if insn does not accept our operands, put them into pseudos. */
1333
1334 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1335 op0 = copy_to_mode_reg (mode0, op0);
1336
1337 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1338 || (flag_force_mem && GET_CODE (temp) == MEM))
1339 temp = gen_reg_rtx (GET_MODE (temp));
1340
1341 pat = GEN_FCN (icode) (temp, op0);
1342
1343 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1344 add_equal_note (pat, temp, code, op0, 0);
1345
1346 emit_insn (pat);
1347
1348 if (temp != target)
1349 emit_move_insn (target, temp);
1350}
1351\f
1352/* Emit code to perform a series of operations on a multi-word quantity, one
1353 word at a time.
1354
d45cf215 1355 Such a block is preceded by a CLOBBER of the output, consists of multiple
77c9c6c2
RK
1356 insns, each setting one word of the output, and followed by a SET copying
1357 the output to itself.
1358
1359 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1360 note indicating that it doesn't conflict with the (also multi-word)
1361 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1362 notes.
1363
1364 INSNS is a block of code generated to perform the operation, not including
1365 the CLOBBER and final copy. All insns that compute intermediate values
1366 are first emitted, followed by the block as described above. Only
1367 INSNs are allowed in the block; no library calls or jumps may be
1368 present.
1369
1370 TARGET, OP0, and OP1 are the output and inputs of the operations,
1371 respectively. OP1 may be zero for a unary operation.
1372
1373 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1374 on the last insn.
1375
1376 If TARGET is not a register, INSNS is simply emitted with no special
1377 processing.
1378
1379 The final insn emitted is returned. */
1380
1381rtx
1382emit_no_conflict_block (insns, target, op0, op1, equiv)
1383 rtx insns;
1384 rtx target;
1385 rtx op0, op1;
1386 rtx equiv;
1387{
1388 rtx prev, next, first, last, insn;
1389
1390 if (GET_CODE (target) != REG || reload_in_progress)
1391 return emit_insns (insns);
1392
1393 /* First emit all insns that do not store into words of the output and remove
1394 these from the list. */
1395 for (insn = insns; insn; insn = next)
1396 {
1397 rtx set = 0;
1398 int i;
1399
1400 next = NEXT_INSN (insn);
1401
1402 if (GET_CODE (insn) != INSN)
1403 abort ();
1404
1405 if (GET_CODE (PATTERN (insn)) == SET)
1406 set = PATTERN (insn);
1407 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1408 {
1409 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1410 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1411 {
1412 set = XVECEXP (PATTERN (insn), 0, i);
1413 break;
1414 }
1415 }
1416
1417 if (set == 0)
1418 abort ();
1419
1420 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1421 {
1422 if (PREV_INSN (insn))
1423 NEXT_INSN (PREV_INSN (insn)) = next;
1424 else
1425 insns = next;
1426
1427 if (next)
1428 PREV_INSN (next) = PREV_INSN (insn);
1429
1430 add_insn (insn);
1431 }
1432 }
1433
1434 prev = get_last_insn ();
1435
1436 /* Now write the CLOBBER of the output, followed by the setting of each
1437 of the words, followed by the final copy. */
1438 if (target != op0 && target != op1)
1439 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1440
1441 for (insn = insns; insn; insn = next)
1442 {
1443 next = NEXT_INSN (insn);
1444 add_insn (insn);
1445
1446 if (op1 && GET_CODE (op1) == REG)
1447 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1448 REG_NOTES (insn));
1449
1450 if (op0 && GET_CODE (op0) == REG)
1451 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1452 REG_NOTES (insn));
1453 }
1454
1455 last = emit_move_insn (target, target);
1456 if (equiv)
1457 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1458
1459 if (prev == 0)
1460 first = get_insns ();
1461 else
1462 first = NEXT_INSN (prev);
1463
1464 /* Encapsulate the block so it gets manipulated as a unit. */
1465 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1466 REG_NOTES (first));
1467 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1468
1469 return last;
1470}
1471\f
1472/* Emit code to make a call to a constant function or a library call.
1473
1474 INSNS is a list containing all insns emitted in the call.
1475 These insns leave the result in RESULT. Our block is to copy RESULT
1476 to TARGET, which is logically equivalent to EQUIV.
1477
1478 We first emit any insns that set a pseudo on the assumption that these are
1479 loading constants into registers; doing so allows them to be safely cse'ed
1480 between blocks. Then we emit all the other insns in the block, followed by
1481 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1482 note with an operand of EQUIV.
1483
29ebe69a
RK
1484 Moving assignments to pseudos outside of the block is done to improve
1485 the generated code, but is not required to generate correct code,
1486 hence being unable to move an assignment is not grounds for not making
1487 a libcall block. There are two reasons why it is safe to leave these
1488 insns inside the block: First, we know that these pseudos cannot be
1489 used in generated RTL outside the block since they are created for
1490 temporary purposes within the block. Second, CSE will not record the
1491 values of anything set inside a libcall block, so we know they must
1492 be dead at the end of the block.
1493
77c9c6c2
RK
1494 Except for the first group of insns (the ones setting pseudos), the
1495 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1496
1497void
1498emit_libcall_block (insns, target, result, equiv)
1499 rtx insns;
1500 rtx target;
1501 rtx result;
1502 rtx equiv;
1503{
1504 rtx prev, next, first, last, insn;
1505
1506 /* First emit all insns that set pseudos. Remove them from the list as
29ebe69a
RK
1507 we go. Avoid insns that set pseudo which were referenced in previous
1508 insns. These can be generated by move_by_pieces, for example,
1509 to update an address. */
77c9c6c2
RK
1510
1511 for (insn = insns; insn; insn = next)
1512 {
1513 rtx set = single_set (insn);
1514
1515 next = NEXT_INSN (insn);
1516
1517 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
29ebe69a 1518 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
8d9e73cc
RS
1519 && (insn == insns
1520 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1521 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
77c9c6c2
RK
1522 {
1523 if (PREV_INSN (insn))
1524 NEXT_INSN (PREV_INSN (insn)) = next;
1525 else
1526 insns = next;
1527
1528 if (next)
1529 PREV_INSN (next) = PREV_INSN (insn);
1530
1531 add_insn (insn);
1532 }
1533 }
1534
1535 prev = get_last_insn ();
1536
1537 /* Write the remaining insns followed by the final copy. */
1538
1539 for (insn = insns; insn; insn = next)
1540 {
1541 next = NEXT_INSN (insn);
1542
1543 add_insn (insn);
1544 }
1545
1546 last = emit_move_insn (target, result);
1547 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1548
1549 if (prev == 0)
1550 first = get_insns ();
1551 else
1552 first = NEXT_INSN (prev);
1553
1554 /* Encapsulate the block so it gets manipulated as a unit. */
1555 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1556 REG_NOTES (first));
1557 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1558}
1559\f
1560/* Generate code to store zero in X. */
1561
1562void
1563emit_clr_insn (x)
1564 rtx x;
1565{
1566 emit_move_insn (x, const0_rtx);
1567}
1568
1569/* Generate code to store 1 in X
1570 assuming it contains zero beforehand. */
1571
1572void
1573emit_0_to_1_insn (x)
1574 rtx x;
1575{
1576 emit_move_insn (x, const1_rtx);
1577}
1578
1579/* Generate code to compare X with Y
1580 so that the condition codes are set.
1581
1582 MODE is the mode of the inputs (in case they are const_int).
1583 UNSIGNEDP nonzero says that X and Y are unsigned;
1584 this matters if they need to be widened.
1585
1586 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1587 and ALIGN specifies the known shared alignment of X and Y.
1588
1589 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1590 It is ignored for fixed-point and block comparisons;
1591 it is used only for floating-point comparisons. */
1592
1593void
1594emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1595 rtx x, y;
1596 enum rtx_code comparison;
1597 rtx size;
2aa8f23f 1598 enum machine_mode mode;
77c9c6c2
RK
1599 int unsignedp;
1600 int align;
1601{
1602 enum mode_class class;
1603 enum machine_mode wider_mode;
1604
1605 class = GET_MODE_CLASS (mode);
1606
1607 /* They could both be VOIDmode if both args are immediate constants,
1608 but we should fold that at an earlier stage.
1609 With no special code here, this will call abort,
1610 reminding the programmer to implement such folding. */
1611
1612 if (mode != BLKmode && flag_force_mem)
1613 {
1614 x = force_not_mem (x);
1615 y = force_not_mem (y);
1616 }
1617
1618 /* If we are inside an appropriately-short loop and one operand is an
1619 expensive constant, force it into a register. */
aeedc93f 1620 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
77c9c6c2
RK
1621 x = force_reg (mode, x);
1622
aeedc93f 1623 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
77c9c6c2
RK
1624 y = force_reg (mode, y);
1625
1626 /* Don't let both operands fail to indicate the mode. */
1627 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1628 x = force_reg (mode, x);
1629
1630 /* Handle all BLKmode compares. */
1631
1632 if (mode == BLKmode)
1633 {
1634 emit_queue ();
1635 x = protect_from_queue (x, 0);
1636 y = protect_from_queue (y, 0);
1637
1638 if (size == 0)
1639 abort ();
1640#ifdef HAVE_cmpstrqi
1641 if (HAVE_cmpstrqi
1642 && GET_CODE (size) == CONST_INT
1643 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1644 {
1645 enum machine_mode result_mode
1646 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1647 rtx result = gen_reg_rtx (result_mode);
1648 emit_insn (gen_cmpstrqi (result, x, y, size,
1649 gen_rtx (CONST_INT, VOIDmode, align)));
1650 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1651 }
1652 else
1653#endif
1654#ifdef HAVE_cmpstrhi
1655 if (HAVE_cmpstrhi
1656 && GET_CODE (size) == CONST_INT
1657 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1658 {
1659 enum machine_mode result_mode
1660 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1661 rtx result = gen_reg_rtx (result_mode);
1662 emit_insn (gen_cmpstrhi (result, x, y, size,
1663 gen_rtx (CONST_INT, VOIDmode, align)));
1664 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1665 }
1666 else
1667#endif
1668#ifdef HAVE_cmpstrsi
1669 if (HAVE_cmpstrsi)
1670 {
1671 enum machine_mode result_mode
1672 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1673 rtx result = gen_reg_rtx (result_mode);
1674 emit_insn (gen_cmpstrsi (result, x, y,
1675 convert_to_mode (SImode, size, 1),
1676 gen_rtx (CONST_INT, VOIDmode, align)));
1677 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1678 }
1679 else
1680#endif
1681 {
1682#ifdef TARGET_MEM_FUNCTIONS
86f8eff3 1683 emit_library_call (memcmp_libfunc, 1,
77c9c6c2
RK
1684 TYPE_MODE (integer_type_node), 3,
1685 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1686 size, Pmode);
1687#else
86f8eff3 1688 emit_library_call (bcmp_libfunc, 1,
77c9c6c2
RK
1689 TYPE_MODE (integer_type_node), 3,
1690 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1691 size, Pmode);
1692#endif
1693 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1694 const0_rtx, comparison, 0,
1695 TYPE_MODE (integer_type_node), 0, 0);
1696 }
1697 return;
1698 }
1699
1700 /* Handle some compares against zero. */
1701
1702 if (y == CONST0_RTX (mode)
1703 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1704 {
1705 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1706
1707 emit_queue ();
1708 x = protect_from_queue (x, 0);
1709 y = protect_from_queue (y, 0);
1710
1711 /* Now, if insn does accept these operands, put them into pseudos. */
1712 if (! (*insn_operand_predicate[icode][0])
1713 (x, insn_operand_mode[icode][0]))
1714 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1715
1716 emit_insn (GEN_FCN (icode) (x));
1717 return;
1718 }
1719
1720 /* Handle compares for which there is a directly suitable insn. */
1721
1722 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1723 {
1724 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1725
1726 emit_queue ();
1727 x = protect_from_queue (x, 0);
1728 y = protect_from_queue (y, 0);
1729
1730 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1731 if (! (*insn_operand_predicate[icode][0])
1732 (x, insn_operand_mode[icode][0]))
1733 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1734
1735 if (! (*insn_operand_predicate[icode][1])
1736 (y, insn_operand_mode[icode][1]))
1737 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1738
1739 emit_insn (GEN_FCN (icode) (x, y));
1740 return;
1741 }
1742
1743 /* Try widening if we can find a direct insn that way. */
1744
1745 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1746 {
34e56753 1747 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1748 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1749 {
1750 if (cmp_optab->handlers[(int) wider_mode].insn_code
1751 != CODE_FOR_nothing)
1752 {
1753 x = convert_to_mode (wider_mode, x, unsignedp);
1754 y = convert_to_mode (wider_mode, y, unsignedp);
1755 emit_cmp_insn (x, y, comparison, 0,
1756 wider_mode, unsignedp, align);
1757 return;
1758 }
1759 }
1760 }
1761
1762 /* Handle a lib call just for the mode we are using. */
1763
1764 if (cmp_optab->handlers[(int) mode].libfunc
1765 && class != MODE_FLOAT)
1766 {
1767 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1768 /* If we want unsigned, and this mode has a distinct unsigned
1769 comparison routine, use that. */
1770 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1771 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1772
86f8eff3 1773 emit_library_call (libfunc, 1,
77c9c6c2
RK
1774 SImode, 2, x, mode, y, mode);
1775
1776 /* Integer comparison returns a result that must be compared against 1,
1777 so that even if we do an unsigned compare afterward,
1778 there is still a value that can represent the result "less than". */
1779
1780 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1781 comparison, 0, SImode, unsignedp, 0);
1782 return;
1783 }
1784
1785 if (class == MODE_FLOAT)
1786 emit_float_lib_cmp (x, y, comparison);
1787
1788 else
1789 abort ();
1790}
1791
1792/* Nonzero if a compare of mode MODE can be done straightforwardly
1793 (without splitting it into pieces). */
1794
1795int
1796can_compare_p (mode)
1797 enum machine_mode mode;
1798{
1799 do
1800 {
1801 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1802 return 1;
1803 mode = GET_MODE_WIDER_MODE (mode);
1804 } while (mode != VOIDmode);
1805
1806 return 0;
1807}
1808\f
1809/* Emit a library call comparison between floating point X and Y.
1810 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1811
1812static void
1813emit_float_lib_cmp (x, y, comparison)
1814 rtx x, y;
1815 enum rtx_code comparison;
1816{
1817 enum machine_mode mode = GET_MODE (x);
1818 rtx libfunc;
1819
1820 if (mode == SFmode)
1821 switch (comparison)
1822 {
1823 case EQ:
1824 libfunc = eqsf2_libfunc;
1825 break;
1826
1827 case NE:
1828 libfunc = nesf2_libfunc;
1829 break;
1830
1831 case GT:
1832 libfunc = gtsf2_libfunc;
1833 break;
1834
1835 case GE:
1836 libfunc = gesf2_libfunc;
1837 break;
1838
1839 case LT:
1840 libfunc = ltsf2_libfunc;
1841 break;
1842
1843 case LE:
1844 libfunc = lesf2_libfunc;
1845 break;
1846 }
1847 else if (mode == DFmode)
1848 switch (comparison)
1849 {
1850 case EQ:
1851 libfunc = eqdf2_libfunc;
1852 break;
1853
1854 case NE:
1855 libfunc = nedf2_libfunc;
1856 break;
1857
1858 case GT:
1859 libfunc = gtdf2_libfunc;
1860 break;
1861
1862 case GE:
1863 libfunc = gedf2_libfunc;
1864 break;
1865
1866 case LT:
1867 libfunc = ltdf2_libfunc;
1868 break;
1869
1870 case LE:
1871 libfunc = ledf2_libfunc;
1872 break;
1873 }
b092b471
JW
1874 else if (mode == XFmode)
1875 switch (comparison)
1876 {
1877 case EQ:
1878 libfunc = eqxf2_libfunc;
1879 break;
1880
1881 case NE:
1882 libfunc = nexf2_libfunc;
1883 break;
1884
1885 case GT:
1886 libfunc = gtxf2_libfunc;
1887 break;
1888
1889 case GE:
1890 libfunc = gexf2_libfunc;
1891 break;
1892
1893 case LT:
1894 libfunc = ltxf2_libfunc;
1895 break;
1896
1897 case LE:
1898 libfunc = lexf2_libfunc;
1899 break;
1900 }
1901 else if (mode == TFmode)
1902 switch (comparison)
1903 {
1904 case EQ:
1905 libfunc = eqtf2_libfunc;
1906 break;
1907
1908 case NE:
1909 libfunc = netf2_libfunc;
1910 break;
1911
1912 case GT:
1913 libfunc = gttf2_libfunc;
1914 break;
1915
1916 case GE:
1917 libfunc = getf2_libfunc;
1918 break;
1919
1920 case LT:
1921 libfunc = lttf2_libfunc;
1922 break;
1923
1924 case LE:
1925 libfunc = letf2_libfunc;
1926 break;
1927 }
77c9c6c2
RK
1928 else
1929 {
1930 enum machine_mode wider_mode;
1931
34e56753 1932 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1933 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1934 {
1935 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1936 != CODE_FOR_nothing)
1937 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1938 {
1939 x = convert_to_mode (wider_mode, x, 0);
1940 y = convert_to_mode (wider_mode, y, 0);
1941 emit_float_lib_cmp (x, y, comparison);
1942 return;
1943 }
1944 }
1945 abort ();
1946 }
1947
86f8eff3 1948 emit_library_call (libfunc, 1,
77c9c6c2
RK
1949 SImode, 2, x, mode, y, mode);
1950
1951 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1952 0, SImode, 0, 0);
1953}
1954\f
1955/* Generate code to indirectly jump to a location given in the rtx LOC. */
1956
1957void
1958emit_indirect_jump (loc)
1959 rtx loc;
1960{
1961 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1962 (loc, VOIDmode)))
1963 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1964 loc);
1965
1966 emit_jump_insn (gen_indirect_jump (loc));
9649fb4d 1967 emit_barrier ();
77c9c6c2
RK
1968}
1969\f
1970/* These three functions generate an insn body and return it
1971 rather than emitting the insn.
1972
1973 They do not protect from queued increments,
1974 because they may be used 1) in protect_from_queue itself
1975 and 2) in other passes where there is no queue. */
1976
1977/* Generate and return an insn body to add Y to X. */
1978
1979rtx
1980gen_add2_insn (x, y)
1981 rtx x, y;
1982{
1983 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1984
1985 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1986 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1987 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1988 abort ();
1989
1990 return (GEN_FCN (icode) (x, x, y));
1991}
1992
1993int
1994have_add2_insn (mode)
1995 enum machine_mode mode;
1996{
1997 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1998}
1999
2000/* Generate and return an insn body to subtract Y from X. */
2001
2002rtx
2003gen_sub2_insn (x, y)
2004 rtx x, y;
2005{
2006 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2007
2008 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2009 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2010 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2011 abort ();
2012
2013 return (GEN_FCN (icode) (x, x, y));
2014}
2015
2016int
2017have_sub2_insn (mode)
2018 enum machine_mode mode;
2019{
2020 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2021}
2022
2023/* Generate the body of an instruction to copy Y into X. */
2024
2025rtx
2026gen_move_insn (x, y)
2027 rtx x, y;
2028{
2029 register enum machine_mode mode = GET_MODE (x);
2030 enum insn_code insn_code;
2031
2032 if (mode == VOIDmode)
2033 mode = GET_MODE (y);
2034
2035 insn_code = mov_optab->handlers[(int) mode].insn_code;
2036
2037 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2038 find a mode to do it in. If we have a movcc, use it. Otherwise,
2039 find the MODE_INT mode of the same width. */
2040
2041 if (insn_code == CODE_FOR_nothing)
2042 {
2043 enum machine_mode tmode = VOIDmode;
2044 rtx x1 = x, y1 = y;
2045
2046 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2047 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2048 tmode = CCmode;
2049 else if (GET_MODE_CLASS (mode) == MODE_CC)
2050 for (tmode = QImode; tmode != VOIDmode;
2051 tmode = GET_MODE_WIDER_MODE (tmode))
2052 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2053 break;
2054
2055 if (tmode == VOIDmode)
2056 abort ();
2057
2058 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2059 may call change_address which is not appropriate if we were
2060 called when a reload was in progress. We don't have to worry
2061 about changing the address since the size in bytes is supposed to
2062 be the same. Copy the MEM to change the mode and move any
2063 substitutions from the old MEM to the new one. */
2064
2065 if (reload_in_progress)
2066 {
2067 x = gen_lowpart_common (tmode, x1);
2068 if (x == 0 && GET_CODE (x1) == MEM)
2069 {
2070 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2071 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2072 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2073 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2074 copy_replacements (x1, x);
2075 }
2076
2077 y = gen_lowpart_common (tmode, y1);
2078 if (y == 0 && GET_CODE (y1) == MEM)
2079 {
2080 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2081 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2082 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2083 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2084 copy_replacements (y1, y);
2085 }
2086 }
2087 else
2088 {
2089 x = gen_lowpart (tmode, x);
2090 y = gen_lowpart (tmode, y);
2091 }
2092
2093 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2094 }
2095
2096 return (GEN_FCN (insn_code) (x, y));
2097}
2098\f
2099/* Tables of patterns for extending one integer mode to another. */
34e56753 2100static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
77c9c6c2 2101
34e56753
RS
2102/* Return the insn code used to extend FROM_MODE to TO_MODE.
2103 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2104 no such operation exists, CODE_FOR_nothing will be returned. */
77c9c6c2 2105
34e56753 2106enum insn_code
77c9c6c2
RK
2107can_extend_p (to_mode, from_mode, unsignedp)
2108 enum machine_mode to_mode, from_mode;
2109 int unsignedp;
2110{
34e56753 2111 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
77c9c6c2
RK
2112}
2113
2114/* Generate the body of an insn to extend Y (with mode MFROM)
2115 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2116
2117rtx
2118gen_extend_insn (x, y, mto, mfrom, unsignedp)
2119 rtx x, y;
2120 enum machine_mode mto, mfrom;
2121 int unsignedp;
2122{
34e56753 2123 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
77c9c6c2
RK
2124}
2125
2126static void
2127init_extends ()
2128{
34e56753
RS
2129 enum insn_code *p;
2130
2131 for (p = extendtab[0][0];
2132 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2133 p++)
2134 *p = CODE_FOR_nothing;
77c9c6c2
RK
2135
2136#ifdef HAVE_extendditi2
2137 if (HAVE_extendditi2)
34e56753 2138 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
77c9c6c2
RK
2139#endif
2140#ifdef HAVE_extendsiti2
2141 if (HAVE_extendsiti2)
34e56753 2142 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
77c9c6c2
RK
2143#endif
2144#ifdef HAVE_extendhiti2
2145 if (HAVE_extendhiti2)
34e56753 2146 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
77c9c6c2
RK
2147#endif
2148#ifdef HAVE_extendqiti2
2149 if (HAVE_extendqiti2)
34e56753 2150 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
77c9c6c2
RK
2151#endif
2152#ifdef HAVE_extendsidi2
2153 if (HAVE_extendsidi2)
34e56753 2154 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
77c9c6c2
RK
2155#endif
2156#ifdef HAVE_extendhidi2
2157 if (HAVE_extendhidi2)
34e56753 2158 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
77c9c6c2
RK
2159#endif
2160#ifdef HAVE_extendqidi2
2161 if (HAVE_extendqidi2)
34e56753 2162 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
77c9c6c2
RK
2163#endif
2164#ifdef HAVE_extendhisi2
2165 if (HAVE_extendhisi2)
34e56753 2166 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
77c9c6c2
RK
2167#endif
2168#ifdef HAVE_extendqisi2
2169 if (HAVE_extendqisi2)
34e56753 2170 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
77c9c6c2
RK
2171#endif
2172#ifdef HAVE_extendqihi2
2173 if (HAVE_extendqihi2)
34e56753 2174 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
77c9c6c2
RK
2175#endif
2176
2177#ifdef HAVE_zero_extendditi2
2178 if (HAVE_zero_extendsiti2)
34e56753 2179 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
77c9c6c2
RK
2180#endif
2181#ifdef HAVE_zero_extendsiti2
2182 if (HAVE_zero_extendsiti2)
34e56753 2183 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
77c9c6c2
RK
2184#endif
2185#ifdef HAVE_zero_extendhiti2
2186 if (HAVE_zero_extendhiti2)
34e56753 2187 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
77c9c6c2
RK
2188#endif
2189#ifdef HAVE_zero_extendqiti2
2190 if (HAVE_zero_extendqiti2)
34e56753 2191 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
77c9c6c2
RK
2192#endif
2193#ifdef HAVE_zero_extendsidi2
2194 if (HAVE_zero_extendsidi2)
34e56753 2195 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
77c9c6c2
RK
2196#endif
2197#ifdef HAVE_zero_extendhidi2
2198 if (HAVE_zero_extendhidi2)
34e56753 2199 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
77c9c6c2
RK
2200#endif
2201#ifdef HAVE_zero_extendqidi2
2202 if (HAVE_zero_extendqidi2)
34e56753 2203 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
77c9c6c2
RK
2204#endif
2205#ifdef HAVE_zero_extendhisi2
2206 if (HAVE_zero_extendhisi2)
34e56753 2207 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
77c9c6c2
RK
2208#endif
2209#ifdef HAVE_zero_extendqisi2
2210 if (HAVE_zero_extendqisi2)
34e56753 2211 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
77c9c6c2
RK
2212#endif
2213#ifdef HAVE_zero_extendqihi2
2214 if (HAVE_zero_extendqihi2)
34e56753 2215 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
77c9c6c2
RK
2216#endif
2217}
2218\f
2219/* can_fix_p and can_float_p say whether the target machine
2220 can directly convert a given fixed point type to
2221 a given floating point type, or vice versa.
2222 The returned value is the CODE_FOR_... value to use,
2223 or CODE_FOR_nothing if these modes cannot be directly converted. */
2224
2225static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2226static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2227static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2228
2229/* *TRUNCP_PTR is set to 1 if it is necessary to output
2230 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2231
2232static enum insn_code
2233can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2234 enum machine_mode fltmode, fixmode;
2235 int unsignedp;
2236 int *truncp_ptr;
2237{
2238 *truncp_ptr = 0;
2239 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2240 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2241
2242 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2243 {
2244 *truncp_ptr = 1;
2245 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2246 }
2247 return CODE_FOR_nothing;
2248}
2249
2250static enum insn_code
2251can_float_p (fltmode, fixmode, unsignedp)
2252 enum machine_mode fixmode, fltmode;
2253 int unsignedp;
2254{
2255 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2256}
2257
2258void
2259init_fixtab ()
2260{
2261 enum insn_code *p;
2262 for (p = fixtab[0][0];
2263 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2264 p++)
2265 *p = CODE_FOR_nothing;
2266 for (p = fixtrunctab[0][0];
2267 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2268 p++)
2269 *p = CODE_FOR_nothing;
2270
2271#ifdef HAVE_fixsfqi2
2272 if (HAVE_fixsfqi2)
2273 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2274#endif
2275#ifdef HAVE_fixsfhi2
2276 if (HAVE_fixsfhi2)
2277 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2278#endif
2279#ifdef HAVE_fixsfsi2
2280 if (HAVE_fixsfsi2)
2281 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2282#endif
2283#ifdef HAVE_fixsfdi2
2284 if (HAVE_fixsfdi2)
2285 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2286#endif
2287
2288#ifdef HAVE_fixdfqi2
2289 if (HAVE_fixdfqi2)
2290 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2291#endif
2292#ifdef HAVE_fixdfhi2
2293 if (HAVE_fixdfhi2)
2294 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2295#endif
2296#ifdef HAVE_fixdfsi2
2297 if (HAVE_fixdfsi2)
2298 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2299#endif
2300#ifdef HAVE_fixdfdi2
2301 if (HAVE_fixdfdi2)
2302 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2303#endif
2304#ifdef HAVE_fixdfti2
2305 if (HAVE_fixdfti2)
2306 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2307#endif
2308
b092b471
JW
2309#ifdef HAVE_fixxfqi2
2310 if (HAVE_fixxfqi2)
2311 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2312#endif
2313#ifdef HAVE_fixxfhi2
2314 if (HAVE_fixxfhi2)
2315 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2316#endif
2317#ifdef HAVE_fixxfsi2
2318 if (HAVE_fixxfsi2)
2319 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2320#endif
2321#ifdef HAVE_fixxfdi2
2322 if (HAVE_fixxfdi2)
2323 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2324#endif
2325#ifdef HAVE_fixxfti2
2326 if (HAVE_fixxfti2)
2327 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2328#endif
2329
77c9c6c2
RK
2330#ifdef HAVE_fixtfqi2
2331 if (HAVE_fixtfqi2)
2332 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2333#endif
2334#ifdef HAVE_fixtfhi2
2335 if (HAVE_fixtfhi2)
2336 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2337#endif
2338#ifdef HAVE_fixtfsi2
2339 if (HAVE_fixtfsi2)
2340 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2341#endif
2342#ifdef HAVE_fixtfdi2
2343 if (HAVE_fixtfdi2)
2344 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2345#endif
2346#ifdef HAVE_fixtfti2
2347 if (HAVE_fixtfti2)
2348 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2349#endif
2350
2351#ifdef HAVE_fixunssfqi2
2352 if (HAVE_fixunssfqi2)
2353 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2354#endif
2355#ifdef HAVE_fixunssfhi2
2356 if (HAVE_fixunssfhi2)
2357 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2358#endif
2359#ifdef HAVE_fixunssfsi2
2360 if (HAVE_fixunssfsi2)
2361 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2362#endif
2363#ifdef HAVE_fixunssfdi2
2364 if (HAVE_fixunssfdi2)
2365 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2366#endif
2367
2368#ifdef HAVE_fixunsdfqi2
2369 if (HAVE_fixunsdfqi2)
2370 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2371#endif
2372#ifdef HAVE_fixunsdfhi2
2373 if (HAVE_fixunsdfhi2)
2374 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2375#endif
2376#ifdef HAVE_fixunsdfsi2
2377 if (HAVE_fixunsdfsi2)
2378 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2379#endif
2380#ifdef HAVE_fixunsdfdi2
2381 if (HAVE_fixunsdfdi2)
2382 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2383#endif
2384#ifdef HAVE_fixunsdfti2
2385 if (HAVE_fixunsdfti2)
2386 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2387#endif
2388
b092b471
JW
2389#ifdef HAVE_fixunsxfqi2
2390 if (HAVE_fixunsxfqi2)
2391 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2392#endif
2393#ifdef HAVE_fixunsxfhi2
2394 if (HAVE_fixunsxfhi2)
2395 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2396#endif
2397#ifdef HAVE_fixunsxfsi2
2398 if (HAVE_fixunsxfsi2)
2399 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2400#endif
2401#ifdef HAVE_fixunsxfdi2
2402 if (HAVE_fixunsxfdi2)
2403 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2404#endif
2405#ifdef HAVE_fixunsxfti2
2406 if (HAVE_fixunsxfti2)
2407 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2408#endif
2409
77c9c6c2
RK
2410#ifdef HAVE_fixunstfqi2
2411 if (HAVE_fixunstfqi2)
2412 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2413#endif
2414#ifdef HAVE_fixunstfhi2
2415 if (HAVE_fixunstfhi2)
2416 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2417#endif
2418#ifdef HAVE_fixunstfsi2
2419 if (HAVE_fixunstfsi2)
2420 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2421#endif
2422#ifdef HAVE_fixunstfdi2
2423 if (HAVE_fixunstfdi2)
2424 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2425#endif
2426#ifdef HAVE_fixunstfti2
2427 if (HAVE_fixunstfti2)
2428 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2429#endif
2430
2431#ifdef HAVE_fix_truncsfqi2
2432 if (HAVE_fix_truncsfqi2)
2433 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2434#endif
2435#ifdef HAVE_fix_truncsfhi2
2436 if (HAVE_fix_truncsfhi2)
2437 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2438#endif
2439#ifdef HAVE_fix_truncsfsi2
2440 if (HAVE_fix_truncsfsi2)
2441 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2442#endif
2443#ifdef HAVE_fix_truncsfdi2
2444 if (HAVE_fix_truncsfdi2)
2445 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2446#endif
2447
2448#ifdef HAVE_fix_truncdfqi2
2449 if (HAVE_fix_truncdfsi2)
2450 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2451#endif
2452#ifdef HAVE_fix_truncdfhi2
2453 if (HAVE_fix_truncdfhi2)
2454 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2455#endif
2456#ifdef HAVE_fix_truncdfsi2
2457 if (HAVE_fix_truncdfsi2)
2458 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2459#endif
2460#ifdef HAVE_fix_truncdfdi2
2461 if (HAVE_fix_truncdfdi2)
2462 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2463#endif
2464#ifdef HAVE_fix_truncdfti2
2465 if (HAVE_fix_truncdfti2)
2466 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2467#endif
2468
b092b471
JW
2469#ifdef HAVE_fix_truncxfqi2
2470 if (HAVE_fix_truncxfqi2)
2471 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2472#endif
2473#ifdef HAVE_fix_truncxfhi2
2474 if (HAVE_fix_truncxfhi2)
2475 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2476#endif
2477#ifdef HAVE_fix_truncxfsi2
2478 if (HAVE_fix_truncxfsi2)
2479 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2480#endif
2481#ifdef HAVE_fix_truncxfdi2
2482 if (HAVE_fix_truncxfdi2)
2483 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2484#endif
2485#ifdef HAVE_fix_truncxfti2
2486 if (HAVE_fix_truncxfti2)
2487 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2488#endif
2489
77c9c6c2
RK
2490#ifdef HAVE_fix_trunctfqi2
2491 if (HAVE_fix_trunctfqi2)
2492 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2493#endif
2494#ifdef HAVE_fix_trunctfhi2
2495 if (HAVE_fix_trunctfhi2)
2496 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2497#endif
2498#ifdef HAVE_fix_trunctfsi2
2499 if (HAVE_fix_trunctfsi2)
2500 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2501#endif
2502#ifdef HAVE_fix_trunctfdi2
2503 if (HAVE_fix_trunctfdi2)
2504 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2505#endif
2506#ifdef HAVE_fix_trunctfti2
2507 if (HAVE_fix_trunctfti2)
2508 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2509#endif
2510
2511#ifdef HAVE_fixuns_truncsfqi2
2512 if (HAVE_fixuns_truncsfqi2)
2513 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2514#endif
2515#ifdef HAVE_fixuns_truncsfhi2
2516 if (HAVE_fixuns_truncsfhi2)
2517 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2518#endif
2519#ifdef HAVE_fixuns_truncsfsi2
2520 if (HAVE_fixuns_truncsfsi2)
2521 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2522#endif
2523#ifdef HAVE_fixuns_truncsfdi2
2524 if (HAVE_fixuns_truncsfdi2)
2525 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2526#endif
2527
2528#ifdef HAVE_fixuns_truncdfqi2
2529 if (HAVE_fixuns_truncdfqi2)
2530 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2531#endif
2532#ifdef HAVE_fixuns_truncdfhi2
2533 if (HAVE_fixuns_truncdfhi2)
2534 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2535#endif
2536#ifdef HAVE_fixuns_truncdfsi2
2537 if (HAVE_fixuns_truncdfsi2)
2538 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2539#endif
2540#ifdef HAVE_fixuns_truncdfdi2
2541 if (HAVE_fixuns_truncdfdi2)
2542 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2543#endif
2544#ifdef HAVE_fixuns_truncdfti2
2545 if (HAVE_fixuns_truncdfti2)
2546 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2547#endif
2548
b092b471
JW
2549#ifdef HAVE_fixuns_truncxfqi2
2550 if (HAVE_fixuns_truncxfqi2)
2551 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2552#endif
2553#ifdef HAVE_fixuns_truncxfhi2
2554 if (HAVE_fixuns_truncxfhi2)
2555 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2556#endif
2557#ifdef HAVE_fixuns_truncxfsi2
2558 if (HAVE_fixuns_truncxfsi2)
2559 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2560#endif
2561#ifdef HAVE_fixuns_truncxfdi2
2562 if (HAVE_fixuns_truncxfdi2)
2563 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2564#endif
2565#ifdef HAVE_fixuns_truncxfti2
2566 if (HAVE_fixuns_truncxfti2)
2567 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2568#endif
2569
77c9c6c2
RK
2570#ifdef HAVE_fixuns_trunctfqi2
2571 if (HAVE_fixuns_trunctfqi2)
2572 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2573#endif
2574#ifdef HAVE_fixuns_trunctfhi2
2575 if (HAVE_fixuns_trunctfhi2)
2576 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2577#endif
2578#ifdef HAVE_fixuns_trunctfsi2
2579 if (HAVE_fixuns_trunctfsi2)
2580 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2581#endif
2582#ifdef HAVE_fixuns_trunctfdi2
2583 if (HAVE_fixuns_trunctfdi2)
2584 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2585#endif
2586#ifdef HAVE_fixuns_trunctfti2
2587 if (HAVE_fixuns_trunctfti2)
2588 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2589#endif
2590
2591#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2592 /* This flag says the same insns that convert to a signed fixnum
2593 also convert validly to an unsigned one. */
2594 {
2595 int i;
2596 int j;
2597 for (i = 0; i < NUM_MACHINE_MODES; i++)
2598 for (j = 0; j < NUM_MACHINE_MODES; j++)
2599 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2600 }
2601#endif
2602}
2603
2604void
2605init_floattab ()
2606{
2607 enum insn_code *p;
2608 for (p = floattab[0][0];
2609 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2610 p++)
2611 *p = CODE_FOR_nothing;
2612
2613#ifdef HAVE_floatqisf2
2614 if (HAVE_floatqisf2)
2615 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2616#endif
2617#ifdef HAVE_floathisf2
2618 if (HAVE_floathisf2)
2619 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2620#endif
2621#ifdef HAVE_floatsisf2
2622 if (HAVE_floatsisf2)
2623 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2624#endif
2625#ifdef HAVE_floatdisf2
2626 if (HAVE_floatdisf2)
2627 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2628#endif
2629#ifdef HAVE_floattisf2
2630 if (HAVE_floattisf2)
2631 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2632#endif
2633
2634#ifdef HAVE_floatqidf2
2635 if (HAVE_floatqidf2)
2636 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2637#endif
2638#ifdef HAVE_floathidf2
2639 if (HAVE_floathidf2)
2640 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2641#endif
2642#ifdef HAVE_floatsidf2
2643 if (HAVE_floatsidf2)
2644 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2645#endif
2646#ifdef HAVE_floatdidf2
2647 if (HAVE_floatdidf2)
2648 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2649#endif
2650#ifdef HAVE_floattidf2
2651 if (HAVE_floattidf2)
2652 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2653#endif
2654
b092b471
JW
2655#ifdef HAVE_floatqixf2
2656 if (HAVE_floatqixf2)
2657 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2658#endif
2659#ifdef HAVE_floathixf2
2660 if (HAVE_floathixf2)
2661 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2662#endif
2663#ifdef HAVE_floatsixf2
2664 if (HAVE_floatsixf2)
2665 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2666#endif
2667#ifdef HAVE_floatdixf2
2668 if (HAVE_floatdixf2)
2669 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2670#endif
2671#ifdef HAVE_floattixf2
2672 if (HAVE_floattixf2)
2673 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2674#endif
2675
77c9c6c2
RK
2676#ifdef HAVE_floatqitf2
2677 if (HAVE_floatqitf2)
2678 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2679#endif
2680#ifdef HAVE_floathitf2
2681 if (HAVE_floathitf2)
2682 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2683#endif
2684#ifdef HAVE_floatsitf2
2685 if (HAVE_floatsitf2)
2686 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2687#endif
2688#ifdef HAVE_floatditf2
2689 if (HAVE_floatditf2)
2690 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2691#endif
2692#ifdef HAVE_floattitf2
2693 if (HAVE_floattitf2)
2694 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2695#endif
2696
2697#ifdef HAVE_floatunsqisf2
2698 if (HAVE_floatunsqisf2)
2699 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2700#endif
2701#ifdef HAVE_floatunshisf2
2702 if (HAVE_floatunshisf2)
2703 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2704#endif
2705#ifdef HAVE_floatunssisf2
2706 if (HAVE_floatunssisf2)
2707 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2708#endif
2709#ifdef HAVE_floatunsdisf2
2710 if (HAVE_floatunsdisf2)
2711 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2712#endif
2713#ifdef HAVE_floatunstisf2
2714 if (HAVE_floatunstisf2)
2715 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2716#endif
2717
2718#ifdef HAVE_floatunsqidf2
2719 if (HAVE_floatunsqidf2)
2720 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2721#endif
2722#ifdef HAVE_floatunshidf2
2723 if (HAVE_floatunshidf2)
2724 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2725#endif
2726#ifdef HAVE_floatunssidf2
2727 if (HAVE_floatunssidf2)
2728 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2729#endif
2730#ifdef HAVE_floatunsdidf2
2731 if (HAVE_floatunsdidf2)
2732 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2733#endif
2734#ifdef HAVE_floatunstidf2
2735 if (HAVE_floatunstidf2)
2736 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2737#endif
2738
b092b471
JW
2739#ifdef HAVE_floatunsqixf2
2740 if (HAVE_floatunsqixf2)
2741 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2742#endif
2743#ifdef HAVE_floatunshixf2
2744 if (HAVE_floatunshixf2)
2745 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2746#endif
2747#ifdef HAVE_floatunssixf2
2748 if (HAVE_floatunssixf2)
2749 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2750#endif
2751#ifdef HAVE_floatunsdixf2
2752 if (HAVE_floatunsdixf2)
2753 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2754#endif
2755#ifdef HAVE_floatunstixf2
2756 if (HAVE_floatunstixf2)
2757 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2758#endif
2759
77c9c6c2
RK
2760#ifdef HAVE_floatunsqitf2
2761 if (HAVE_floatunsqitf2)
2762 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2763#endif
2764#ifdef HAVE_floatunshitf2
2765 if (HAVE_floatunshitf2)
2766 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2767#endif
2768#ifdef HAVE_floatunssitf2
2769 if (HAVE_floatunssitf2)
2770 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2771#endif
2772#ifdef HAVE_floatunsditf2
2773 if (HAVE_floatunsditf2)
2774 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2775#endif
2776#ifdef HAVE_floatunstitf2
2777 if (HAVE_floatunstitf2)
2778 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2779#endif
2780}
2781\f
2782/* Generate code to convert FROM to floating point
34e56753 2783 and store in TO. FROM must be fixed point and not VOIDmode.
77c9c6c2
RK
2784 UNSIGNEDP nonzero means regard FROM as unsigned.
2785 Normally this is done by correcting the final value
2786 if it is negative. */
2787
2788void
2789expand_float (to, from, unsignedp)
2790 rtx to, from;
2791 int unsignedp;
2792{
2793 enum insn_code icode;
2794 register rtx target = to;
2795 enum machine_mode fmode, imode;
2796
34e56753
RS
2797 /* Crash now, because we won't be able to decide which mode to use. */
2798 if (GET_MODE (from) == VOIDmode)
2799 abort ();
2800
77c9c6c2
RK
2801 /* Look for an insn to do the conversion. Do it in the specified
2802 modes if possible; otherwise convert either input, output or both to
2803 wider mode. If the integer mode is wider than the mode of FROM,
2804 we can do the conversion signed even if the input is unsigned. */
2805
2806 for (imode = GET_MODE (from); imode != VOIDmode;
2807 imode = GET_MODE_WIDER_MODE (imode))
2808 for (fmode = GET_MODE (to); fmode != VOIDmode;
2809 fmode = GET_MODE_WIDER_MODE (fmode))
2810 {
2811 int doing_unsigned = unsignedp;
2812
2813 icode = can_float_p (fmode, imode, unsignedp);
2814 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2815 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2816
2817 if (icode != CODE_FOR_nothing)
2818 {
2819 to = protect_from_queue (to, 1);
2820
2821 if (imode != GET_MODE (from))
2822 from = convert_to_mode (imode, from, unsignedp);
2823 else
2824 from = protect_from_queue (from, 0);
2825
2826 if (fmode != GET_MODE (to))
2827 target = gen_reg_rtx (fmode);
2828
2829 emit_unop_insn (icode, target, from,
2830 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2831
2832 if (target != to)
2833 convert_move (to, target, 0);
2834 return;
2835 }
2836 }
2837
2838#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2839
2840 /* Unsigned integer, and no way to convert directly.
2841 Convert as signed, then conditionally adjust the result. */
2842 if (unsignedp)
2843 {
2844 rtx label = gen_label_rtx ();
2845 rtx temp;
2846 REAL_VALUE_TYPE offset;
2847
2848 emit_queue ();
2849
2850 to = protect_from_queue (to, 1);
2851 from = protect_from_queue (from, 0);
2852
2853 if (flag_force_mem)
2854 from = force_not_mem (from);
2855
2856 /* If we are about to do some arithmetic to correct for an
2857 unsigned operand, do it in a pseudo-register. */
2858
2859 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2860 target = gen_reg_rtx (GET_MODE (to));
2861
2862 /* Convert as signed integer to floating. */
2863 expand_float (target, from, 0);
2864
2865 /* If FROM is negative (and therefore TO is negative),
2866 correct its value by 2**bitwidth. */
2867
2868 do_pending_stack_adjust ();
2869 emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2870 emit_jump_insn (gen_bge (label));
2871 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2872 Rather than setting up a dconst_dot_5, let's hope SCO
2873 fixes the bug. */
2874 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2875 temp = expand_binop (GET_MODE (to), add_optab, target,
2876 immed_real_const_1 (offset, GET_MODE (to)),
2877 target, 0, OPTAB_LIB_WIDEN);
2878 if (temp != target)
2879 emit_move_insn (target, temp);
2880 do_pending_stack_adjust ();
2881 emit_label (label);
2882 }
2883 else
2884#endif
2885
b092b471
JW
2886 /* No hardware instruction available; call a library rotine to convert from
2887 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
77c9c6c2 2888 {
6bce1b78 2889 rtx libfcn;
77c9c6c2
RK
2890 rtx insns;
2891
2892 to = protect_from_queue (to, 1);
2893
2894 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2895 from = convert_to_mode (SImode, from, unsignedp);
2896 else
2897 from = protect_from_queue (from, 0);
2898
2899 if (flag_force_mem)
2900 from = force_not_mem (from);
2901
2902 if (GET_MODE (to) == SFmode)
2903 {
2904 if (GET_MODE (from) == SImode)
6bce1b78 2905 libfcn = floatsisf_libfunc;
77c9c6c2 2906 else if (GET_MODE (from) == DImode)
6bce1b78 2907 libfcn = floatdisf_libfunc;
b092b471
JW
2908 else if (GET_MODE (from) == TImode)
2909 libfcn = floattisf_libfunc;
77c9c6c2
RK
2910 else
2911 abort ();
2912 }
2913 else if (GET_MODE (to) == DFmode)
2914 {
2915 if (GET_MODE (from) == SImode)
6bce1b78 2916 libfcn = floatsidf_libfunc;
77c9c6c2 2917 else if (GET_MODE (from) == DImode)
6bce1b78 2918 libfcn = floatdidf_libfunc;
b092b471
JW
2919 else if (GET_MODE (from) == TImode)
2920 libfcn = floattidf_libfunc;
2921 else
2922 abort ();
2923 }
2924 else if (GET_MODE (to) == XFmode)
2925 {
2926 if (GET_MODE (from) == SImode)
2927 libfcn = floatsixf_libfunc;
2928 else if (GET_MODE (from) == DImode)
2929 libfcn = floatdixf_libfunc;
2930 else if (GET_MODE (from) == TImode)
2931 libfcn = floattixf_libfunc;
2932 else
2933 abort ();
2934 }
2935 else if (GET_MODE (to) == TFmode)
2936 {
2937 if (GET_MODE (from) == SImode)
2938 libfcn = floatsitf_libfunc;
2939 else if (GET_MODE (from) == DImode)
2940 libfcn = floatditf_libfunc;
2941 else if (GET_MODE (from) == TImode)
2942 libfcn = floattitf_libfunc;
77c9c6c2
RK
2943 else
2944 abort ();
2945 }
2946 else
2947 abort ();
2948
2949 start_sequence ();
2950
86f8eff3 2951 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
2952 insns = get_insns ();
2953 end_sequence ();
2954
2955 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2956 gen_rtx (FLOAT, GET_MODE (to), from));
2957 }
2958
2959 /* Copy result to requested destination
2960 if we have been computing in a temp location. */
2961
2962 if (target != to)
2963 {
2964 if (GET_MODE (target) == GET_MODE (to))
2965 emit_move_insn (to, target);
2966 else
2967 convert_move (to, target, 0);
2968 }
2969}
2970\f
2971/* expand_fix: generate code to convert FROM to fixed point
2972 and store in TO. FROM must be floating point. */
2973
2974static rtx
2975ftruncify (x)
2976 rtx x;
2977{
2978 rtx temp = gen_reg_rtx (GET_MODE (x));
2979 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2980}
2981
2982void
2983expand_fix (to, from, unsignedp)
2984 register rtx to, from;
2985 int unsignedp;
2986{
2987 enum insn_code icode;
2988 register rtx target = to;
2989 enum machine_mode fmode, imode;
2990 int must_trunc = 0;
6bce1b78 2991 rtx libfcn = 0;
77c9c6c2
RK
2992
2993 /* We first try to find a pair of modes, one real and one integer, at
2994 least as wide as FROM and TO, respectively, in which we can open-code
2995 this conversion. If the integer mode is wider than the mode of TO,
2996 we can do the conversion either signed or unsigned. */
2997
2998 for (imode = GET_MODE (to); imode != VOIDmode;
2999 imode = GET_MODE_WIDER_MODE (imode))
3000 for (fmode = GET_MODE (from); fmode != VOIDmode;
3001 fmode = GET_MODE_WIDER_MODE (fmode))
3002 {
3003 int doing_unsigned = unsignedp;
3004
3005 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3006 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3007 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3008
3009 if (icode != CODE_FOR_nothing)
3010 {
3011 to = protect_from_queue (to, 1);
3012
3013 if (fmode != GET_MODE (from))
3014 from = convert_to_mode (fmode, from, 0);
3015 else
3016 from = protect_from_queue (from, 0);
3017
3018 if (must_trunc)
3019 from = ftruncify (from);
3020
3021 if (imode != GET_MODE (to))
3022 target = gen_reg_rtx (imode);
3023
3024 emit_unop_insn (icode, target, from,
3025 doing_unsigned ? UNSIGNED_FIX : FIX);
3026 if (target != to)
3027 convert_move (to, target, unsignedp);
3028 return;
3029 }
3030 }
3031
3032#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3033 /* For an unsigned conversion, there is one more way to do it.
3034 If we have a signed conversion, we generate code that compares
3035 the real value to the largest representable positive number. If if
3036 is smaller, the conversion is done normally. Otherwise, subtract
3037 one plus the highest signed number, convert, and add it back.
3038
3039 We only need to check all real modes, since we know we didn't find
6dc42e49 3040 anything with a wider integer mode. */
77c9c6c2
RK
3041
3042 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
3043 for (fmode = GET_MODE (from); fmode != VOIDmode;
3044 fmode = GET_MODE_WIDER_MODE (fmode))
3045 /* Make sure we won't lose significant bits doing this. */
3046 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3047 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3048 &must_trunc))
3049 {
3050 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3051 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3052 rtx limit = immed_real_const_1 (offset, fmode);
3053 rtx lab1 = gen_label_rtx ();
3054 rtx lab2 = gen_label_rtx ();
3055 rtx insn;
3056
3057 emit_queue ();
3058 to = protect_from_queue (to, 1);
3059 from = protect_from_queue (from, 0);
3060
3061 if (flag_force_mem)
3062 from = force_not_mem (from);
3063
3064 if (fmode != GET_MODE (from))
3065 from = convert_to_mode (fmode, from, 0);
3066
3067 /* See if we need to do the subtraction. */
3068 do_pending_stack_adjust ();
3069 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
3070 emit_jump_insn (gen_bge (lab1));
3071
3072 /* If not, do the signed "fix" and branch around fixup code. */
3073 expand_fix (to, from, 0);
3074 emit_jump_insn (gen_jump (lab2));
3075 emit_barrier ();
3076
3077 /* Otherwise, subtract 2**(N-1), convert to signed number,
3078 then add 2**(N-1). Do the addition using XOR since this
3079 will often generate better code. */
3080 emit_label (lab1);
3081 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3082 0, 0, OPTAB_LIB_WIDEN);
3083 expand_fix (to, target, 0);
3084 target = expand_binop (GET_MODE (to), xor_optab, to,
3085 gen_rtx (CONST_INT, VOIDmode,
3086 1 << (bitsize - 1)),
3087 to, 1, OPTAB_LIB_WIDEN);
3088
3089 if (target != to)
3090 emit_move_insn (to, target);
3091
3092 emit_label (lab2);
3093
3094 /* Make a place for a REG_NOTE and add it. */
3095 insn = emit_move_insn (to, to);
3096 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3097 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3098 from), REG_NOTES (insn));
3099
3100 return;
3101 }
3102#endif
3103
3104 /* We can't do it with an insn, so use a library call. But first ensure
3105 that the mode of TO is at least as wide as SImode, since those are the
3106 only library calls we know about. */
3107
3108 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3109 {
3110 target = gen_reg_rtx (SImode);
3111
3112 expand_fix (target, from, unsignedp);
3113 }
3114 else if (GET_MODE (from) == SFmode)
3115 {
3116 if (GET_MODE (to) == SImode)
6bce1b78 3117 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
77c9c6c2 3118 else if (GET_MODE (to) == DImode)
6bce1b78 3119 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
b092b471
JW
3120 else if (GET_MODE (to) == TImode)
3121 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
77c9c6c2
RK
3122 else
3123 abort ();
3124 }
3125 else if (GET_MODE (from) == DFmode)
3126 {
3127 if (GET_MODE (to) == SImode)
6bce1b78 3128 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
77c9c6c2 3129 else if (GET_MODE (to) == DImode)
6bce1b78 3130 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
b092b471
JW
3131 else if (GET_MODE (to) == TImode)
3132 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3133 else
3134 abort ();
3135 }
3136 else if (GET_MODE (from) == XFmode)
3137 {
3138 if (GET_MODE (to) == SImode)
3139 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3140 else if (GET_MODE (to) == DImode)
3141 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3142 else if (GET_MODE (to) == TImode)
3143 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3144 else
3145 abort ();
3146 }
3147 else if (GET_MODE (from) == TFmode)
3148 {
3149 if (GET_MODE (to) == SImode)
3150 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3151 else if (GET_MODE (to) == DImode)
3152 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3153 else if (GET_MODE (to) == TImode)
3154 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
77c9c6c2
RK
3155 else
3156 abort ();
3157 }
3158 else
3159 abort ();
3160
6bce1b78 3161 if (libfcn)
77c9c6c2
RK
3162 {
3163 rtx insns;
3164
3165 to = protect_from_queue (to, 1);
3166 from = protect_from_queue (from, 0);
3167
3168 if (flag_force_mem)
3169 from = force_not_mem (from);
3170
3171 start_sequence ();
3172
86f8eff3 3173 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
3174 insns = get_insns ();
3175 end_sequence ();
3176
3177 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3178 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3179 GET_MODE (to), from));
3180 }
3181
3182 if (GET_MODE (to) == GET_MODE (target))
3183 emit_move_insn (to, target);
3184 else
3185 convert_move (to, target, 0);
3186}
3187\f
3188static optab
3189init_optab (code)
3190 enum rtx_code code;
3191{
3192 int i;
3193 optab op = (optab) xmalloc (sizeof (struct optab));
3194 op->code = code;
3195 for (i = 0; i < NUM_MACHINE_MODES; i++)
3196 {
3197 op->handlers[i].insn_code = CODE_FOR_nothing;
3198 op->handlers[i].libfunc = 0;
3199 }
3200 return op;
3201}
3202
b092b471
JW
3203/* Initialize the libfunc fields of an entire group of entries in some
3204 optab. Each entry is set equal to a string consisting of a leading
3205 pair of underscores followed by a generic operation name followed by
3206 a mode name (downshifted to lower case) followed by a single character
3207 representing the number of operands for the given operation (which is
3208 usually one of the characters '2', '3', or '4').
3209
3210 OPTABLE is the table in which libfunc fields are to be initialized.
3211 FIRST_MODE is the first machine mode index in the given optab to
3212 initialize.
3213 LAST_MODE is the last machine mode index in the given optab to
3214 initialize.
3215 OPNAME is the generic (string) name of the operation.
3216 SUFFIX is the character which specifies the number of operands for
3217 the given generic operation.
3218*/
3219
3220static void
3221init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3222 register optab optable;
3223 register char *opname;
3224 register enum machine_mode first_mode;
3225 register enum machine_mode last_mode;
3226 register char suffix;
3227{
3228 register enum machine_mode mode;
3229 register unsigned opname_len = strlen (opname);
3230
3231 for (mode = first_mode; mode <= last_mode; mode++)
3232 {
3233 register char *mname = mode_name[(int) mode];
3234 register unsigned mname_len = strlen (mname);
3235 register char *libfunc_name
3236 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3237 register char *p;
3238 register char *q;
3239
3240 p = libfunc_name;
3241 *p++ = '_';
3242 *p++ = '_';
3243 for (q = opname; *q; )
3244 *p++ = *q++;
3245 for (q = mname; *q; q++)
3246 *p++ = tolower (*q);
3247 *p++ = suffix;
3248 *p++ = '\0';
3249 optable->handlers[(int) mode].libfunc
3250 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3251 }
3252}
3253
3254/* Initialize the libfunc fields of an entire group of entries in some
3255 optab which correspond to all integer mode operations. The parameters
3256 have the same meaning as similarly named ones for the `init_libfuncs'
3257 routine. (See above). */
3258
3259static void
3260init_integral_libfuncs (optable, opname, suffix)
3261 register optab optable;
3262 register char *opname;
3263 register char suffix;
3264{
3265 init_libfuncs (optable, SImode, TImode, opname, suffix);
3266}
3267
3268/* Initialize the libfunc fields of an entire group of entries in some
3269 optab which correspond to all real mode operations. The parameters
3270 have the same meaning as similarly named ones for the `init_libfuncs'
3271 routine. (See above). */
3272
3273static void
3274init_floating_libfuncs (optable, opname, suffix)
3275 register optab optable;
3276 register char *opname;
3277 register char suffix;
3278{
3279 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3280}
3281
77c9c6c2
RK
3282/* Call this once to initialize the contents of the optabs
3283 appropriately for the current target machine. */
3284
3285void
3286init_optabs ()
3287{
3288 int i;
3289
3290 init_fixtab ();
3291 init_floattab ();
3292 init_extends ();
3293
3294 add_optab = init_optab (PLUS);
3295 sub_optab = init_optab (MINUS);
3296 smul_optab = init_optab (MULT);
3297 smul_widen_optab = init_optab (UNKNOWN);
3298 umul_widen_optab = init_optab (UNKNOWN);
3299 sdiv_optab = init_optab (DIV);
3300 sdivmod_optab = init_optab (UNKNOWN);
3301 udiv_optab = init_optab (UDIV);
3302 udivmod_optab = init_optab (UNKNOWN);
3303 smod_optab = init_optab (MOD);
3304 umod_optab = init_optab (UMOD);
3305 flodiv_optab = init_optab (DIV);
3306 ftrunc_optab = init_optab (UNKNOWN);
3307 and_optab = init_optab (AND);
3308 ior_optab = init_optab (IOR);
3309 xor_optab = init_optab (XOR);
3310 ashl_optab = init_optab (ASHIFT);
3311 ashr_optab = init_optab (ASHIFTRT);
3312 lshl_optab = init_optab (LSHIFT);
3313 lshr_optab = init_optab (LSHIFTRT);
3314 rotl_optab = init_optab (ROTATE);
3315 rotr_optab = init_optab (ROTATERT);
3316 smin_optab = init_optab (SMIN);
3317 smax_optab = init_optab (SMAX);
3318 umin_optab = init_optab (UMIN);
3319 umax_optab = init_optab (UMAX);
3320 mov_optab = init_optab (UNKNOWN);
3321 movstrict_optab = init_optab (UNKNOWN);
3322 cmp_optab = init_optab (UNKNOWN);
3323 ucmp_optab = init_optab (UNKNOWN);
3324 tst_optab = init_optab (UNKNOWN);
3325 neg_optab = init_optab (NEG);
3326 abs_optab = init_optab (ABS);
3327 one_cmpl_optab = init_optab (NOT);
3328 ffs_optab = init_optab (FFS);
d45cf215 3329 sqrt_optab = init_optab (SQRT);
19c3fc24 3330 strlen_optab = init_optab (UNKNOWN);
77c9c6c2
RK
3331
3332#ifdef HAVE_addqi3
3333 if (HAVE_addqi3)
3334 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3335#endif
3336#ifdef HAVE_addhi3
3337 if (HAVE_addhi3)
3338 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3339#endif
3340#ifdef HAVE_addpsi3
3341 if (HAVE_addpsi3)
3342 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3343#endif
3344#ifdef HAVE_addsi3
3345 if (HAVE_addsi3)
3346 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3347#endif
3348#ifdef HAVE_adddi3
3349 if (HAVE_adddi3)
3350 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3351#endif
3352#ifdef HAVE_addti3
3353 if (HAVE_addti3)
3354 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3355#endif
3356#ifdef HAVE_addsf3
3357 if (HAVE_addsf3)
3358 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3359#endif
3360#ifdef HAVE_adddf3
3361 if (HAVE_adddf3)
3362 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3363#endif
b092b471
JW
3364#ifdef HAVE_addxf3
3365 if (HAVE_addxf3)
3366 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3367#endif
77c9c6c2
RK
3368#ifdef HAVE_addtf3
3369 if (HAVE_addtf3)
3370 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3371#endif
b092b471
JW
3372 init_integral_libfuncs (add_optab, "add", '3');
3373 init_floating_libfuncs (add_optab, "add", '3');
77c9c6c2
RK
3374
3375#ifdef HAVE_subqi3
3376 if (HAVE_subqi3)
3377 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3378#endif
3379#ifdef HAVE_subhi3
3380 if (HAVE_subhi3)
3381 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3382#endif
3383#ifdef HAVE_subpsi3
3384 if (HAVE_subpsi3)
3385 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3386#endif
3387#ifdef HAVE_subsi3
3388 if (HAVE_subsi3)
3389 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3390#endif
3391#ifdef HAVE_subdi3
3392 if (HAVE_subdi3)
3393 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3394#endif
3395#ifdef HAVE_subti3
3396 if (HAVE_subti3)
ded40dfe 3397 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
77c9c6c2
RK
3398#endif
3399#ifdef HAVE_subsf3
3400 if (HAVE_subsf3)
3401 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3402#endif
3403#ifdef HAVE_subdf3
3404 if (HAVE_subdf3)
3405 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3406#endif
b092b471
JW
3407#ifdef HAVE_subxf3
3408 if (HAVE_subxf3)
3409 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3410#endif
77c9c6c2
RK
3411#ifdef HAVE_subtf3
3412 if (HAVE_subtf3)
3413 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3414#endif
b092b471
JW
3415 init_integral_libfuncs (sub_optab, "sub", '3');
3416 init_floating_libfuncs (sub_optab, "sub", '3');
77c9c6c2
RK
3417
3418#ifdef HAVE_mulqi3
3419 if (HAVE_mulqi3)
3420 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3421#endif
3422#ifdef HAVE_mulhi3
3423 if (HAVE_mulhi3)
3424 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3425#endif
3426#ifdef HAVE_mulpsi3
3427 if (HAVE_mulpsi3)
3428 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3429#endif
3430#ifdef HAVE_mulsi3
3431 if (HAVE_mulsi3)
3432 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3433#endif
3434#ifdef HAVE_muldi3
3435 if (HAVE_muldi3)
3436 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3437#endif
3438#ifdef HAVE_multi3
3439 if (HAVE_multi3)
3440 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3441#endif
3442#ifdef HAVE_mulsf3
3443 if (HAVE_mulsf3)
3444 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3445#endif
3446#ifdef HAVE_muldf3
3447 if (HAVE_muldf3)
3448 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3449#endif
b092b471
JW
3450#ifdef HAVE_mulxf3
3451 if (HAVE_mulxf3)
3452 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3453#endif
77c9c6c2
RK
3454#ifdef HAVE_multf3
3455 if (HAVE_multf3)
3456 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3457#endif
b092b471
JW
3458 init_integral_libfuncs (smul_optab, "mul", '3');
3459 init_floating_libfuncs (smul_optab, "mul", '3');
77c9c6c2
RK
3460
3461#ifdef MULSI3_LIBCALL
3462 smul_optab->handlers[(int) SImode].libfunc
3463 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
77c9c6c2
RK
3464#endif
3465#ifdef MULDI3_LIBCALL
3466 smul_optab->handlers[(int) DImode].libfunc
3467 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
77c9c6c2 3468#endif
b092b471
JW
3469#ifdef MULTI3_LIBCALL
3470 smul_optab->handlers[(int) TImode].libfunc
3471 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3472#endif
77c9c6c2
RK
3473
3474#ifdef HAVE_mulqihi3
3475 if (HAVE_mulqihi3)
3476 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3477#endif
3478#ifdef HAVE_mulhisi3
3479 if (HAVE_mulhisi3)
3480 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3481#endif
3482#ifdef HAVE_mulsidi3
3483 if (HAVE_mulsidi3)
3484 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3485#endif
3486#ifdef HAVE_mulditi3
3487 if (HAVE_mulditi3)
3488 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3489#endif
3490
3491#ifdef HAVE_umulqihi3
3492 if (HAVE_umulqihi3)
3493 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3494#endif
3495#ifdef HAVE_umulhisi3
3496 if (HAVE_umulhisi3)
3497 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3498#endif
3499#ifdef HAVE_umulsidi3
3500 if (HAVE_umulsidi3)
3501 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3502#endif
3503#ifdef HAVE_umulditi3
3504 if (HAVE_umulditi3)
3505 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3506#endif
3507
3508#ifdef HAVE_divqi3
3509 if (HAVE_divqi3)
3510 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3511#endif
3512#ifdef HAVE_divhi3
3513 if (HAVE_divhi3)
3514 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3515#endif
3516#ifdef HAVE_divpsi3
3517 if (HAVE_divpsi3)
3518 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3519#endif
3520#ifdef HAVE_divsi3
3521 if (HAVE_divsi3)
3522 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3523#endif
3524#ifdef HAVE_divdi3
3525 if (HAVE_divdi3)
3526 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3527#endif
3528#ifdef HAVE_divti3
3529 if (HAVE_divti3)
3530 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3531#endif
b092b471 3532 init_integral_libfuncs (sdiv_optab, "div", '3');
77c9c6c2
RK
3533
3534#ifdef DIVSI3_LIBCALL
3535 sdiv_optab->handlers[(int) SImode].libfunc
3536 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
77c9c6c2
RK
3537#endif
3538#ifdef DIVDI3_LIBCALL
3539 sdiv_optab->handlers[(int) DImode].libfunc
3540 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
b092b471
JW
3541#endif
3542#ifdef DIVTI3_LIBCALL
3543 sdiv_optab->handlers[(int) TImode].libfunc
3544 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
77c9c6c2
RK
3545#endif
3546
3547#ifdef HAVE_udivqi3
3548 if (HAVE_udivqi3)
3549 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3550#endif
3551#ifdef HAVE_udivhi3
3552 if (HAVE_udivhi3)
3553 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3554#endif
3555#ifdef HAVE_udivpsi3
3556 if (HAVE_udivpsi3)
3557 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3558#endif
3559#ifdef HAVE_udivsi3
3560 if (HAVE_udivsi3)
3561 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3562#endif
3563#ifdef HAVE_udivdi3
3564 if (HAVE_udivdi3)
3565 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3566#endif
3567#ifdef HAVE_udivti3
3568 if (HAVE_udivti3)
3569 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3570#endif
b092b471 3571 init_integral_libfuncs (udiv_optab, "udiv", '3');
77c9c6c2
RK
3572
3573#ifdef UDIVSI3_LIBCALL
3574 udiv_optab->handlers[(int) SImode].libfunc
3575 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
77c9c6c2
RK
3576#endif
3577#ifdef UDIVDI3_LIBCALL
3578 udiv_optab->handlers[(int) DImode].libfunc
3579 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
b092b471
JW
3580#endif
3581#ifdef UDIVTI3_LIBCALL
3582 udiv_optab->handlers[(int) TImode].libfunc
3583 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
77c9c6c2
RK
3584#endif
3585
3586#ifdef HAVE_divmodqi4
3587 if (HAVE_divmodqi4)
3588 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3589#endif
3590#ifdef HAVE_divmodhi4
3591 if (HAVE_divmodhi4)
3592 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3593#endif
3594#ifdef HAVE_divmodsi4
3595 if (HAVE_divmodsi4)
3596 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3597#endif
3598#ifdef HAVE_divmoddi4
3599 if (HAVE_divmoddi4)
3600 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3601#endif
3602#ifdef HAVE_divmodti4
3603 if (HAVE_divmodti4)
3604 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3605#endif
b092b471 3606 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
77c9c6c2
RK
3607
3608#ifdef HAVE_udivmodqi4
3609 if (HAVE_udivmodqi4)
3610 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3611#endif
3612#ifdef HAVE_udivmodhi4
3613 if (HAVE_udivmodhi4)
3614 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3615#endif
3616#ifdef HAVE_udivmodsi4
3617 if (HAVE_udivmodsi4)
3618 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3619#endif
3620#ifdef HAVE_udivmoddi4
3621 if (HAVE_udivmoddi4)
3622 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3623#endif
3624#ifdef HAVE_udivmodti4
3625 if (HAVE_udivmodti4)
3626 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3627#endif
b092b471 3628 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
77c9c6c2
RK
3629
3630#ifdef HAVE_modqi3
3631 if (HAVE_modqi3)
3632 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3633#endif
3634#ifdef HAVE_modhi3
3635 if (HAVE_modhi3)
3636 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3637#endif
3638#ifdef HAVE_modpsi3
3639 if (HAVE_modpsi3)
3640 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3641#endif
3642#ifdef HAVE_modsi3
3643 if (HAVE_modsi3)
3644 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3645#endif
3646#ifdef HAVE_moddi3
3647 if (HAVE_moddi3)
3648 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3649#endif
3650#ifdef HAVE_modti3
3651 if (HAVE_modti3)
3652 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3653#endif
b092b471 3654 init_integral_libfuncs (smod_optab, "mod", '3');
77c9c6c2
RK
3655
3656#ifdef MODSI3_LIBCALL
3657 smod_optab->handlers[(int) SImode].libfunc
3658 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
77c9c6c2
RK
3659#endif
3660#ifdef MODDI3_LIBCALL
3661 smod_optab->handlers[(int) DImode].libfunc
3662 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
b092b471
JW
3663#endif
3664#ifdef MODTI3_LIBCALL
3665 smod_optab->handlers[(int) TImode].libfunc
3666 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
77c9c6c2
RK
3667#endif
3668
3669#ifdef HAVE_umodqi3
3670 if (HAVE_umodqi3)
3671 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3672#endif
3673#ifdef HAVE_umodhi3
3674 if (HAVE_umodhi3)
3675 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3676#endif
3677#ifdef HAVE_umodpsi3
3678 if (HAVE_umodpsi3)
3679 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3680#endif
3681#ifdef HAVE_umodsi3
3682 if (HAVE_umodsi3)
3683 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3684#endif
3685#ifdef HAVE_umoddi3
3686 if (HAVE_umoddi3)
3687 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3688#endif
3689#ifdef HAVE_umodti3
3690 if (HAVE_umodti3)
3691 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3692#endif
b092b471 3693 init_integral_libfuncs (umod_optab, "umod", '3');
77c9c6c2
RK
3694
3695#ifdef UMODSI3_LIBCALL
3696 umod_optab->handlers[(int) SImode].libfunc
3697 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
77c9c6c2
RK
3698#endif
3699#ifdef UMODDI3_LIBCALL
3700 umod_optab->handlers[(int) DImode].libfunc
3701 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
b092b471
JW
3702#endif
3703#ifdef UMODTI3_LIBCALL
3704 umod_optab->handlers[(int) TImode].libfunc
3705 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
77c9c6c2
RK
3706#endif
3707
3708#ifdef HAVE_divsf3
3709 if (HAVE_divsf3)
3710 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3711#endif
3712#ifdef HAVE_divdf3
3713 if (HAVE_divdf3)
3714 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3715#endif
b092b471
JW
3716#ifdef HAVE_divxf3
3717 if (HAVE_divxf3)
3718 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3719#endif
77c9c6c2
RK
3720#ifdef HAVE_divtf3
3721 if (HAVE_divtf3)
3722 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3723#endif
b092b471 3724 init_floating_libfuncs (flodiv_optab, "div", '3');
77c9c6c2
RK
3725
3726#ifdef HAVE_ftruncsf2
3727 if (HAVE_ftruncsf2)
3728 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3729#endif
3730#ifdef HAVE_ftruncdf2
3731 if (HAVE_ftruncdf2)
3732 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3733#endif
b092b471
JW
3734#ifdef HAVE_ftruncxf2
3735 if (HAVE_ftruncxf2)
3736 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3737#endif
77c9c6c2
RK
3738#ifdef HAVE_ftrunctf2
3739 if (HAVE_ftrunctf2)
3740 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3741#endif
b092b471 3742 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
77c9c6c2
RK
3743
3744#ifdef HAVE_andqi3
3745 if (HAVE_andqi3)
3746 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3747#endif
3748#ifdef HAVE_andhi3
3749 if (HAVE_andhi3)
3750 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3751#endif
3752#ifdef HAVE_andpsi3
3753 if (HAVE_andpsi3)
3754 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3755#endif
3756#ifdef HAVE_andsi3
3757 if (HAVE_andsi3)
3758 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3759#endif
3760#ifdef HAVE_anddi3
3761 if (HAVE_anddi3)
3762 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3763#endif
3764#ifdef HAVE_andti3
3765 if (HAVE_andti3)
3766 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3767#endif
b092b471 3768 init_integral_libfuncs (and_optab, "and", '3');
77c9c6c2
RK
3769
3770#ifdef HAVE_iorqi3
3771 if (HAVE_iorqi3)
3772 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3773#endif
3774#ifdef HAVE_iorhi3
3775 if (HAVE_iorhi3)
3776 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3777#endif
3778#ifdef HAVE_iorpsi3
3779 if (HAVE_iorpsi3)
3780 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3781#endif
3782#ifdef HAVE_iorsi3
3783 if (HAVE_iorsi3)
3784 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3785#endif
3786#ifdef HAVE_iordi3
3787 if (HAVE_iordi3)
3788 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3789#endif
3790#ifdef HAVE_iorti3
3791 if (HAVE_iorti3)
3792 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3793#endif
b092b471 3794 init_integral_libfuncs (ior_optab, "ior", '3');
77c9c6c2
RK
3795
3796#ifdef HAVE_xorqi3
3797 if (HAVE_xorqi3)
3798 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3799#endif
3800#ifdef HAVE_xorhi3
3801 if (HAVE_xorhi3)
3802 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3803#endif
3804#ifdef HAVE_xorpsi3
3805 if (HAVE_xorpsi3)
3806 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3807#endif
3808#ifdef HAVE_xorsi3
3809 if (HAVE_xorsi3)
3810 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3811#endif
3812#ifdef HAVE_xordi3
3813 if (HAVE_xordi3)
3814 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3815#endif
3816#ifdef HAVE_xorti3
3817 if (HAVE_xorti3)
3818 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3819#endif
b092b471 3820 init_integral_libfuncs (xor_optab, "xor", '3');
77c9c6c2
RK
3821
3822#ifdef HAVE_ashlqi3
3823 if (HAVE_ashlqi3)
3824 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3825#endif
3826#ifdef HAVE_ashlhi3
3827 if (HAVE_ashlhi3)
3828 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3829#endif
3830#ifdef HAVE_ashlpsi3
3831 if (HAVE_ashlpsi3)
3832 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3833#endif
3834#ifdef HAVE_ashlsi3
3835 if (HAVE_ashlsi3)
3836 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3837#endif
3838#ifdef HAVE_ashldi3
3839 if (HAVE_ashldi3)
3840 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3841#endif
3842#ifdef HAVE_ashlti3
3843 if (HAVE_ashlti3)
3844 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3845#endif
b092b471 3846 init_integral_libfuncs (ashl_optab, "ashl", '3');
77c9c6c2
RK
3847
3848#ifdef HAVE_ashrqi3
3849 if (HAVE_ashrqi3)
3850 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3851#endif
3852#ifdef HAVE_ashrhi3
3853 if (HAVE_ashrhi3)
3854 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3855#endif
3856#ifdef HAVE_ashrpsi3
3857 if (HAVE_ashrpsi3)
3858 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3859#endif
3860#ifdef HAVE_ashrsi3
3861 if (HAVE_ashrsi3)
3862 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3863#endif
3864#ifdef HAVE_ashrdi3
3865 if (HAVE_ashrdi3)
3866 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3867#endif
3868#ifdef HAVE_ashrti3
3869 if (HAVE_ashrti3)
3870 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3871#endif
b092b471 3872 init_integral_libfuncs (ashr_optab, "ashr", '3');
77c9c6c2
RK
3873
3874#ifdef HAVE_lshlqi3
3875 if (HAVE_lshlqi3)
3876 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3877#endif
3878#ifdef HAVE_lshlhi3
3879 if (HAVE_lshlhi3)
3880 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3881#endif
3882#ifdef HAVE_lshlpsi3
3883 if (HAVE_lshlpsi3)
3884 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3885#endif
3886#ifdef HAVE_lshlsi3
3887 if (HAVE_lshlsi3)
3888 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3889#endif
3890#ifdef HAVE_lshldi3
3891 if (HAVE_lshldi3)
3892 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3893#endif
3894#ifdef HAVE_lshlti3
3895 if (HAVE_lshlti3)
3896 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3897#endif
b092b471 3898 init_integral_libfuncs (lshl_optab, "lshl", '3');
77c9c6c2
RK
3899
3900#ifdef HAVE_lshrqi3
3901 if (HAVE_lshrqi3)
3902 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3903#endif
3904#ifdef HAVE_lshrhi3
3905 if (HAVE_lshrhi3)
3906 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3907#endif
3908#ifdef HAVE_lshrpsi3
3909 if (HAVE_lshrpsi3)
3910 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3911#endif
3912#ifdef HAVE_lshrsi3
3913 if (HAVE_lshrsi3)
3914 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3915#endif
3916#ifdef HAVE_lshrdi3
3917 if (HAVE_lshrdi3)
3918 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3919#endif
3920#ifdef HAVE_lshrti3
3921 if (HAVE_lshrti3)
3922 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3923#endif
b092b471 3924 init_integral_libfuncs (lshr_optab, "lshr", '3');
77c9c6c2
RK
3925
3926#ifdef HAVE_rotlqi3
3927 if (HAVE_rotlqi3)
3928 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3929#endif
3930#ifdef HAVE_rotlhi3
3931 if (HAVE_rotlhi3)
3932 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3933#endif
3934#ifdef HAVE_rotlpsi3
3935 if (HAVE_rotlpsi3)
3936 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3937#endif
3938#ifdef HAVE_rotlsi3
3939 if (HAVE_rotlsi3)
3940 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3941#endif
3942#ifdef HAVE_rotldi3
3943 if (HAVE_rotldi3)
3944 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3945#endif
3946#ifdef HAVE_rotlti3
3947 if (HAVE_rotlti3)
3948 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3949#endif
b092b471 3950 init_integral_libfuncs (rotl_optab, "rotl", '3');
77c9c6c2
RK
3951
3952#ifdef HAVE_rotrqi3
3953 if (HAVE_rotrqi3)
3954 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3955#endif
3956#ifdef HAVE_rotrhi3
3957 if (HAVE_rotrhi3)
3958 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3959#endif
3960#ifdef HAVE_rotrpsi3
3961 if (HAVE_rotrpsi3)
3962 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3963#endif
3964#ifdef HAVE_rotrsi3
3965 if (HAVE_rotrsi3)
3966 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3967#endif
3968#ifdef HAVE_rotrdi3
3969 if (HAVE_rotrdi3)
3970 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3971#endif
3972#ifdef HAVE_rotrti3
3973 if (HAVE_rotrti3)
3974 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3975#endif
b092b471 3976 init_integral_libfuncs (rotr_optab, "rotr", '3');
77c9c6c2
RK
3977
3978#ifdef HAVE_sminqi3
3979 if (HAVE_sminqi3)
3980 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3981#endif
3982#ifdef HAVE_sminhi3
3983 if (HAVE_sminhi3)
3984 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3985#endif
3986#ifdef HAVE_sminsi3
3987 if (HAVE_sminsi3)
3988 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3989#endif
3990#ifdef HAVE_smindi3
3991 if (HAVE_smindi3)
3992 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3993#endif
3994#ifdef HAVE_sminti3
3995 if (HAVE_sminti3)
3996 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3997#endif
b092b471
JW
3998#ifdef HAVE_minsf3
3999 if (HAVE_minsf3)
4000 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4001#endif
4002#ifdef HAVE_mindf3
4003 if (HAVE_mindf3)
4004 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
77c9c6c2 4005#endif
b092b471
JW
4006#ifdef HAVE_minxf3
4007 if (HAVE_minxf3)
4008 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
77c9c6c2 4009#endif
b092b471
JW
4010#ifdef HAVE_mintf3
4011 if (HAVE_mintf3)
4012 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
77c9c6c2 4013#endif
b092b471
JW
4014 init_integral_libfuncs (smin_optab, "min", '3');
4015 init_floating_libfuncs (smin_optab, "min", '3');
77c9c6c2
RK
4016
4017#ifdef HAVE_smaxqi3
4018 if (HAVE_smaxqi3)
4019 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4020#endif
4021#ifdef HAVE_smaxhi3
4022 if (HAVE_smaxhi3)
4023 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4024#endif
4025#ifdef HAVE_smaxsi3
4026 if (HAVE_smaxsi3)
4027 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4028#endif
4029#ifdef HAVE_smaxdi3
4030 if (HAVE_smaxdi3)
4031 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4032#endif
4033#ifdef HAVE_smaxti3
4034 if (HAVE_smaxti3)
4035 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4036#endif
b092b471
JW
4037#ifdef HAVE_maxsf3
4038 if (HAVE_maxsf3)
4039 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
77c9c6c2 4040#endif
b092b471
JW
4041#ifdef HAVE_maxdf3
4042 if (HAVE_maxdf3)
4043 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
77c9c6c2 4044#endif
b092b471
JW
4045#ifdef HAVE_maxxf3
4046 if (HAVE_maxxf3)
4047 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
77c9c6c2 4048#endif
b092b471
JW
4049#ifdef HAVE_maxtf3
4050 if (HAVE_maxtf3)
4051 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4052#endif
4053 init_integral_libfuncs (smax_optab, "max", '3');
4054 init_floating_libfuncs (smax_optab, "max", '3');
77c9c6c2
RK
4055
4056#ifdef HAVE_uminqi3
4057 if (HAVE_uminqi3)
4058 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4059#endif
4060#ifdef HAVE_uminhi3
4061 if (HAVE_uminhi3)
4062 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4063#endif
4064#ifdef HAVE_uminsi3
4065 if (HAVE_uminsi3)
4066 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4067#endif
4068#ifdef HAVE_umindi3
4069 if (HAVE_umindi3)
4070 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4071#endif
4072#ifdef HAVE_uminti3
4073 if (HAVE_uminti3)
4074 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4075#endif
b092b471 4076 init_integral_libfuncs (umin_optab, "umin", '3');
77c9c6c2
RK
4077
4078#ifdef HAVE_umaxqi3
4079 if (HAVE_umaxqi3)
4080 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4081#endif
4082#ifdef HAVE_umaxhi3
4083 if (HAVE_umaxhi3)
4084 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4085#endif
4086#ifdef HAVE_umaxsi3
4087 if (HAVE_umaxsi3)
4088 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4089#endif
4090#ifdef HAVE_umaxdi3
4091 if (HAVE_umaxdi3)
4092 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4093#endif
4094#ifdef HAVE_umaxti3
4095 if (HAVE_umaxti3)
4096 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4097#endif
b092b471 4098 init_integral_libfuncs (umax_optab, "umax", '3');
77c9c6c2
RK
4099
4100#ifdef HAVE_negqi2
4101 if (HAVE_negqi2)
4102 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4103#endif
4104#ifdef HAVE_neghi2
4105 if (HAVE_neghi2)
4106 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4107#endif
4108#ifdef HAVE_negpsi2
4109 if (HAVE_negpsi2)
4110 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4111#endif
4112#ifdef HAVE_negsi2
4113 if (HAVE_negsi2)
4114 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4115#endif
4116#ifdef HAVE_negdi2
4117 if (HAVE_negdi2)
4118 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4119#endif
4120#ifdef HAVE_negti2
4121 if (HAVE_negti2)
4122 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4123#endif
4124#ifdef HAVE_negsf2
4125 if (HAVE_negsf2)
4126 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4127#endif
4128#ifdef HAVE_negdf2
4129 if (HAVE_negdf2)
4130 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4131#endif
b092b471
JW
4132#ifdef HAVE_negxf2
4133 if (HAVE_negxf2)
4134 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4135#endif
77c9c6c2
RK
4136#ifdef HAVE_negtf2
4137 if (HAVE_negtf2)
4138 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4139#endif
b092b471
JW
4140 init_integral_libfuncs (neg_optab, "neg", '2');
4141 init_floating_libfuncs (neg_optab, "neg", '2');
77c9c6c2
RK
4142
4143#ifdef HAVE_absqi2
4144 if (HAVE_absqi2)
4145 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4146#endif
4147#ifdef HAVE_abshi2
4148 if (HAVE_abshi2)
4149 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4150#endif
4151#ifdef HAVE_abspsi2
4152 if (HAVE_abspsi2)
4153 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4154#endif
4155#ifdef HAVE_abssi2
4156 if (HAVE_abssi2)
4157 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4158#endif
4159#ifdef HAVE_absdi2
4160 if (HAVE_absdi2)
4161 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4162#endif
4163#ifdef HAVE_absti2
4164 if (HAVE_absti2)
4165 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4166#endif
4167#ifdef HAVE_abssf2
4168 if (HAVE_abssf2)
4169 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4170#endif
4171#ifdef HAVE_absdf2
4172 if (HAVE_absdf2)
4173 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4174#endif
b092b471
JW
4175#ifdef HAVE_absxf2
4176 if (HAVE_absxf2)
4177 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4178#endif
77c9c6c2
RK
4179#ifdef HAVE_abstf2
4180 if (HAVE_abstf2)
4181 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4182#endif
4183 /* No library calls here! If there is no abs instruction,
4184 expand_expr will generate a conditional negation. */
4185
d45cf215
RS
4186#ifdef HAVE_sqrtqi2
4187 if (HAVE_sqrtqi2)
4188 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4189#endif
4190#ifdef HAVE_sqrthi2
4191 if (HAVE_sqrthi2)
4192 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4193#endif
4194#ifdef HAVE_sqrtpsi2
4195 if (HAVE_sqrtpsi2)
4196 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4197#endif
4198#ifdef HAVE_sqrtsi2
4199 if (HAVE_sqrtsi2)
4200 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4201#endif
4202#ifdef HAVE_sqrtdi2
4203 if (HAVE_sqrtdi2)
4204 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4205#endif
4206#ifdef HAVE_sqrtti2
4207 if (HAVE_sqrtti2)
4208 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4209#endif
4210#ifdef HAVE_sqrtsf2
4211 if (HAVE_sqrtsf2)
4212 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4213#endif
4214#ifdef HAVE_sqrtdf2
4215 if (HAVE_sqrtdf2)
4216 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4217#endif
4218#ifdef HAVE_sqrttf2
4219 if (HAVE_sqrttf2)
4220 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4221#endif
4222 /* No library calls here! If there is no sqrt instruction expand_builtin
4223 should force the library call. */
4224
19c3fc24
RS
4225#ifdef HAVE_strlenqi
4226 if (HAVE_strlenqi)
4227 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4228#endif
4229#ifdef HAVE_strlenhi
4230 if (HAVE_strlenhi)
4231 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4232#endif
4233#ifdef HAVE_strlenpsi
4234 if (HAVE_strlenpsi)
4235 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4236#endif
4237#ifdef HAVE_strlensi
4238 if (HAVE_strlensi)
4239 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4240#endif
4241#ifdef HAVE_strlendi
4242 if (HAVE_strlendi)
4243 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4244#endif
4245#ifdef HAVE_strlenti
4246 if (HAVE_strlenti)
4247 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4248#endif
4249 /* No library calls here! If there is no strlen instruction expand_builtin
4250 should force the library call. */
4251
77c9c6c2
RK
4252#ifdef HAVE_one_cmplqi2
4253 if (HAVE_one_cmplqi2)
4254 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4255#endif
4256#ifdef HAVE_one_cmplhi2
4257 if (HAVE_one_cmplhi2)
4258 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4259#endif
4260#ifdef HAVE_one_cmplpsi2
4261 if (HAVE_one_cmplpsi2)
4262 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4263#endif
4264#ifdef HAVE_one_cmplsi2
4265 if (HAVE_one_cmplsi2)
4266 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4267#endif
4268#ifdef HAVE_one_cmpldi2
4269 if (HAVE_one_cmpldi2)
4270 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4271#endif
4272#ifdef HAVE_one_cmplti2
4273 if (HAVE_one_cmplti2)
4274 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4275#endif
b092b471 4276 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
77c9c6c2
RK
4277
4278#ifdef HAVE_ffsqi2
4279 if (HAVE_ffsqi2)
4280 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4281#endif
4282#ifdef HAVE_ffshi2
4283 if (HAVE_ffshi2)
4284 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4285#endif
4286#ifdef HAVE_ffspsi2
4287 if (HAVE_ffspsi2)
4288 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4289#endif
4290#ifdef HAVE_ffssi2
4291 if (HAVE_ffssi2)
4292 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4293#endif
4294#ifdef HAVE_ffsdi2
4295 if (HAVE_ffsdi2)
4296 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4297#endif
4298#ifdef HAVE_ffsti2
4299 if (HAVE_ffsti2)
4300 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4301#endif
b092b471 4302 init_integral_libfuncs (ffs_optab, "ffs", '2');
77c9c6c2
RK
4303
4304#ifdef HAVE_movqi
4305 if (HAVE_movqi)
4306 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4307#endif
4308#ifdef HAVE_movhi
4309 if (HAVE_movhi)
4310 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4311#endif
4312#ifdef HAVE_movpsi
4313 if (HAVE_movpsi)
4314 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4315#endif
4316#ifdef HAVE_movsi
4317 if (HAVE_movsi)
4318 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4319#endif
4320#ifdef HAVE_movdi
4321 if (HAVE_movdi)
4322 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4323#endif
4324#ifdef HAVE_movti
4325 if (HAVE_movti)
4326 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4327#endif
4328#ifdef HAVE_movsf
4329 if (HAVE_movsf)
4330 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4331#endif
4332#ifdef HAVE_movdf
4333 if (HAVE_movdf)
4334 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4335#endif
b092b471
JW
4336#ifdef HAVE_movxf
4337 if (HAVE_movxf)
4338 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4339#endif
77c9c6c2
RK
4340#ifdef HAVE_movtf
4341 if (HAVE_movtf)
4342 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4343#endif
4344#ifdef HAVE_movcc
4345 if (HAVE_movcc)
4346 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4347#endif
4348
4349#ifdef EXTRA_CC_MODES
4350 init_mov_optab ();
4351#endif
4352
4353#ifdef HAVE_movstrictqi
4354 if (HAVE_movstrictqi)
4355 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4356#endif
4357#ifdef HAVE_movstricthi
4358 if (HAVE_movstricthi)
4359 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4360#endif
4361#ifdef HAVE_movstrictpsi
4362 if (HAVE_movstrictpsi)
4363 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4364#endif
4365#ifdef HAVE_movstrictsi
4366 if (HAVE_movstrictsi)
4367 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4368#endif
4369#ifdef HAVE_movstrictdi
4370 if (HAVE_movstrictdi)
4371 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4372#endif
4373#ifdef HAVE_movstrictti
4374 if (HAVE_movstrictti)
4375 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4376#endif
4377
4378#ifdef HAVE_cmpqi
4379 if (HAVE_cmpqi)
4380 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4381#endif
4382#ifdef HAVE_cmphi
4383 if (HAVE_cmphi)
4384 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4385#endif
4386#ifdef HAVE_cmppsi
4387 if (HAVE_cmppsi)
4388 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4389#endif
4390#ifdef HAVE_cmpsi
4391 if (HAVE_cmpsi)
4392 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4393#endif
4394#ifdef HAVE_cmpdi
4395 if (HAVE_cmpdi)
4396 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4397#endif
4398#ifdef HAVE_cmpti
4399 if (HAVE_cmpti)
4400 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4401#endif
4402#ifdef HAVE_cmpsf
4403 if (HAVE_cmpsf)
4404 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4405#endif
4406#ifdef HAVE_cmpdf
4407 if (HAVE_cmpdf)
4408 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4409#endif
b092b471
JW
4410#ifdef HAVE_cmpxf
4411 if (HAVE_cmpxf)
4412 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4413#endif
77c9c6c2
RK
4414#ifdef HAVE_cmptf
4415 if (HAVE_cmptf)
4416 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4417#endif
b092b471
JW
4418 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4419 init_integral_libfuncs (cmp_optab, "cmp", '2');
4420 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4421 init_floating_libfuncs (cmp_optab, "cmp", '2');
4422
77c9c6c2
RK
4423#ifdef HAVE_tstqi
4424 if (HAVE_tstqi)
4425 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4426#endif
4427#ifdef HAVE_tsthi
4428 if (HAVE_tsthi)
4429 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4430#endif
4431#ifdef HAVE_tstpsi
4432 if (HAVE_tstpsi)
4433 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4434#endif
4435#ifdef HAVE_tstsi
4436 if (HAVE_tstsi)
4437 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4438#endif
4439#ifdef HAVE_tstdi
4440 if (HAVE_tstdi)
4441 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4442#endif
4443#ifdef HAVE_tstti
4444 if (HAVE_tstti)
4445 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4446#endif
4447#ifdef HAVE_tstsf
4448 if (HAVE_tstsf)
4449 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4450#endif
4451#ifdef HAVE_tstdf
4452 if (HAVE_tstdf)
4453 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4454#endif
b092b471
JW
4455#ifdef HAVE_tstxf
4456 if (HAVE_tstxf)
4457 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4458#endif
77c9c6c2
RK
4459#ifdef HAVE_tsttf
4460 if (HAVE_tsttf)
4461 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4462#endif
77c9c6c2
RK
4463
4464#ifdef HAVE_beq
4465 if (HAVE_beq)
4466 bcc_gen_fctn[(int) EQ] = gen_beq;
4467#endif
4468#ifdef HAVE_bne
4469 if (HAVE_bne)
4470 bcc_gen_fctn[(int) NE] = gen_bne;
4471#endif
4472#ifdef HAVE_bgt
4473 if (HAVE_bgt)
4474 bcc_gen_fctn[(int) GT] = gen_bgt;
4475#endif
4476#ifdef HAVE_bge
4477 if (HAVE_bge)
4478 bcc_gen_fctn[(int) GE] = gen_bge;
4479#endif
4480#ifdef HAVE_bgtu
4481 if (HAVE_bgtu)
4482 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4483#endif
4484#ifdef HAVE_bgeu
4485 if (HAVE_bgeu)
4486 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4487#endif
4488#ifdef HAVE_blt
4489 if (HAVE_blt)
4490 bcc_gen_fctn[(int) LT] = gen_blt;
4491#endif
4492#ifdef HAVE_ble
4493 if (HAVE_ble)
4494 bcc_gen_fctn[(int) LE] = gen_ble;
4495#endif
4496#ifdef HAVE_bltu
4497 if (HAVE_bltu)
4498 bcc_gen_fctn[(int) LTU] = gen_bltu;
4499#endif
4500#ifdef HAVE_bleu
4501 if (HAVE_bleu)
4502 bcc_gen_fctn[(int) LEU] = gen_bleu;
4503#endif
4504
4505 for (i = 0; i < NUM_RTX_CODE; i++)
4506 setcc_gen_code[i] = CODE_FOR_nothing;
4507
4508#ifdef HAVE_seq
4509 if (HAVE_seq)
4510 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4511#endif
4512#ifdef HAVE_sne
4513 if (HAVE_sne)
4514 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4515#endif
4516#ifdef HAVE_sgt
4517 if (HAVE_sgt)
4518 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4519#endif
4520#ifdef HAVE_sge
4521 if (HAVE_sge)
4522 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4523#endif
4524#ifdef HAVE_sgtu
4525 if (HAVE_sgtu)
4526 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4527#endif
4528#ifdef HAVE_sgeu
4529 if (HAVE_sgeu)
4530 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4531#endif
4532#ifdef HAVE_slt
4533 if (HAVE_slt)
4534 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4535#endif
4536#ifdef HAVE_sle
4537 if (HAVE_sle)
4538 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4539#endif
4540#ifdef HAVE_sltu
4541 if (HAVE_sltu)
4542 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4543#endif
4544#ifdef HAVE_sleu
4545 if (HAVE_sleu)
4546 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4547#endif
4548
4549 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
b092b471
JW
4550 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4551 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4552 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4553 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4554
77c9c6c2 4555 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
b092b471
JW
4556 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4557 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4558 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4559 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4560
77c9c6c2
RK
4561 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4562 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4563 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4564 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4565 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4566 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
b092b471 4567
77c9c6c2
RK
4568 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4569 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4570 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4571 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4572 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4573 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
b092b471 4574
77c9c6c2
RK
4575 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4576 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4577 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4578 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4579 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4580 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
b092b471
JW
4581
4582 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4583 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4584 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4585 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4586 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4587 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4588
4589 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4590 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4591 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4592 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4593 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4594 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4595
6bce1b78 4596 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
b092b471
JW
4597 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4598 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4599
6bce1b78 4600 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
b092b471
JW
4601 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4602 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4603
4604 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4605 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4606 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4607
4608 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4609 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4610 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4611
6bce1b78
RK
4612 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4613 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
b092b471
JW
4614 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4615
6bce1b78
RK
4616 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4617 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
b092b471
JW
4618 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4619
4620 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4621 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4622 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4623
4624 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4625 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4626 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4627
6bce1b78
RK
4628 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4629 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
b092b471
JW
4630 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4631
6bce1b78
RK
4632 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4633 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
b092b471
JW
4634 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4635
4636 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4637 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4638 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4639
4640 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4641 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4642 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
77c9c6c2 4643}
7e1966ca
JVA
4644\f
4645#ifdef BROKEN_LDEXP
4646
4647/* SCO 3.2 apparently has a broken ldexp. */
4648
4649double
4650ldexp(x,n)
4651 double x;
4652 int n;
4653{
4654 if (n > 0)
4655 while (n--)
4656 x *= 2;
4657
4658 return x;
4659}
4660#endif /* BROKEN_LDEXP */
This page took 0.713908 seconds and 5 git commands to generate.