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