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