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