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