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