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