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