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