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