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