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