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