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