]> 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
RK
1356 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1357 && ! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1358 && ! reg_used_between_p (SET_DEST (set), insns, insn))
77c9c6c2
RK
1359 {
1360 if (PREV_INSN (insn))
1361 NEXT_INSN (PREV_INSN (insn)) = next;
1362 else
1363 insns = next;
1364
1365 if (next)
1366 PREV_INSN (next) = PREV_INSN (insn);
1367
1368 add_insn (insn);
1369 }
1370 }
1371
1372 prev = get_last_insn ();
1373
1374 /* Write the remaining insns followed by the final copy. */
1375
1376 for (insn = insns; insn; insn = next)
1377 {
1378 next = NEXT_INSN (insn);
1379
1380 add_insn (insn);
1381 }
1382
1383 last = emit_move_insn (target, result);
1384 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1385
1386 if (prev == 0)
1387 first = get_insns ();
1388 else
1389 first = NEXT_INSN (prev);
1390
1391 /* Encapsulate the block so it gets manipulated as a unit. */
1392 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1393 REG_NOTES (first));
1394 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1395}
1396\f
1397/* Generate code to store zero in X. */
1398
1399void
1400emit_clr_insn (x)
1401 rtx x;
1402{
1403 emit_move_insn (x, const0_rtx);
1404}
1405
1406/* Generate code to store 1 in X
1407 assuming it contains zero beforehand. */
1408
1409void
1410emit_0_to_1_insn (x)
1411 rtx x;
1412{
1413 emit_move_insn (x, const1_rtx);
1414}
1415
1416/* Generate code to compare X with Y
1417 so that the condition codes are set.
1418
1419 MODE is the mode of the inputs (in case they are const_int).
1420 UNSIGNEDP nonzero says that X and Y are unsigned;
1421 this matters if they need to be widened.
1422
1423 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1424 and ALIGN specifies the known shared alignment of X and Y.
1425
1426 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1427 It is ignored for fixed-point and block comparisons;
1428 it is used only for floating-point comparisons. */
1429
1430void
1431emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1432 rtx x, y;
1433 enum rtx_code comparison;
1434 rtx size;
2aa8f23f 1435 enum machine_mode mode;
77c9c6c2
RK
1436 int unsignedp;
1437 int align;
1438{
1439 enum mode_class class;
1440 enum machine_mode wider_mode;
1441
1442 class = GET_MODE_CLASS (mode);
1443
1444 /* They could both be VOIDmode if both args are immediate constants,
1445 but we should fold that at an earlier stage.
1446 With no special code here, this will call abort,
1447 reminding the programmer to implement such folding. */
1448
1449 if (mode != BLKmode && flag_force_mem)
1450 {
1451 x = force_not_mem (x);
1452 y = force_not_mem (y);
1453 }
1454
1455 /* If we are inside an appropriately-short loop and one operand is an
1456 expensive constant, force it into a register. */
aeedc93f 1457 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
77c9c6c2
RK
1458 x = force_reg (mode, x);
1459
aeedc93f 1460 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
77c9c6c2
RK
1461 y = force_reg (mode, y);
1462
1463 /* Don't let both operands fail to indicate the mode. */
1464 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1465 x = force_reg (mode, x);
1466
1467 /* Handle all BLKmode compares. */
1468
1469 if (mode == BLKmode)
1470 {
1471 emit_queue ();
1472 x = protect_from_queue (x, 0);
1473 y = protect_from_queue (y, 0);
1474
1475 if (size == 0)
1476 abort ();
1477#ifdef HAVE_cmpstrqi
1478 if (HAVE_cmpstrqi
1479 && GET_CODE (size) == CONST_INT
1480 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1481 {
1482 enum machine_mode result_mode
1483 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1484 rtx result = gen_reg_rtx (result_mode);
1485 emit_insn (gen_cmpstrqi (result, x, y, size,
1486 gen_rtx (CONST_INT, VOIDmode, align)));
1487 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1488 }
1489 else
1490#endif
1491#ifdef HAVE_cmpstrhi
1492 if (HAVE_cmpstrhi
1493 && GET_CODE (size) == CONST_INT
1494 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1495 {
1496 enum machine_mode result_mode
1497 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1498 rtx result = gen_reg_rtx (result_mode);
1499 emit_insn (gen_cmpstrhi (result, x, y, size,
1500 gen_rtx (CONST_INT, VOIDmode, align)));
1501 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1502 }
1503 else
1504#endif
1505#ifdef HAVE_cmpstrsi
1506 if (HAVE_cmpstrsi)
1507 {
1508 enum machine_mode result_mode
1509 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1510 rtx result = gen_reg_rtx (result_mode);
1511 emit_insn (gen_cmpstrsi (result, x, y,
1512 convert_to_mode (SImode, size, 1),
1513 gen_rtx (CONST_INT, VOIDmode, align)));
1514 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1515 }
1516 else
1517#endif
1518 {
1519#ifdef TARGET_MEM_FUNCTIONS
86f8eff3 1520 emit_library_call (memcmp_libfunc, 1,
77c9c6c2
RK
1521 TYPE_MODE (integer_type_node), 3,
1522 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1523 size, Pmode);
1524#else
86f8eff3 1525 emit_library_call (bcmp_libfunc, 1,
77c9c6c2
RK
1526 TYPE_MODE (integer_type_node), 3,
1527 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1528 size, Pmode);
1529#endif
1530 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1531 const0_rtx, comparison, 0,
1532 TYPE_MODE (integer_type_node), 0, 0);
1533 }
1534 return;
1535 }
1536
1537 /* Handle some compares against zero. */
1538
1539 if (y == CONST0_RTX (mode)
1540 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1541 {
1542 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1543
1544 emit_queue ();
1545 x = protect_from_queue (x, 0);
1546 y = protect_from_queue (y, 0);
1547
1548 /* Now, if insn does accept these operands, put them into pseudos. */
1549 if (! (*insn_operand_predicate[icode][0])
1550 (x, insn_operand_mode[icode][0]))
1551 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1552
1553 emit_insn (GEN_FCN (icode) (x));
1554 return;
1555 }
1556
1557 /* Handle compares for which there is a directly suitable insn. */
1558
1559 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1560 {
1561 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1562
1563 emit_queue ();
1564 x = protect_from_queue (x, 0);
1565 y = protect_from_queue (y, 0);
1566
1567 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1568 if (! (*insn_operand_predicate[icode][0])
1569 (x, insn_operand_mode[icode][0]))
1570 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1571
1572 if (! (*insn_operand_predicate[icode][1])
1573 (y, insn_operand_mode[icode][1]))
1574 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1575
1576 emit_insn (GEN_FCN (icode) (x, y));
1577 return;
1578 }
1579
1580 /* Try widening if we can find a direct insn that way. */
1581
1582 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1583 {
34e56753 1584 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1585 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1586 {
1587 if (cmp_optab->handlers[(int) wider_mode].insn_code
1588 != CODE_FOR_nothing)
1589 {
1590 x = convert_to_mode (wider_mode, x, unsignedp);
1591 y = convert_to_mode (wider_mode, y, unsignedp);
1592 emit_cmp_insn (x, y, comparison, 0,
1593 wider_mode, unsignedp, align);
1594 return;
1595 }
1596 }
1597 }
1598
1599 /* Handle a lib call just for the mode we are using. */
1600
1601 if (cmp_optab->handlers[(int) mode].libfunc
1602 && class != MODE_FLOAT)
1603 {
1604 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1605 /* If we want unsigned, and this mode has a distinct unsigned
1606 comparison routine, use that. */
1607 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1608 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1609
86f8eff3 1610 emit_library_call (libfunc, 1,
77c9c6c2
RK
1611 SImode, 2, x, mode, y, mode);
1612
1613 /* Integer comparison returns a result that must be compared against 1,
1614 so that even if we do an unsigned compare afterward,
1615 there is still a value that can represent the result "less than". */
1616
1617 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1618 comparison, 0, SImode, unsignedp, 0);
1619 return;
1620 }
1621
1622 if (class == MODE_FLOAT)
1623 emit_float_lib_cmp (x, y, comparison);
1624
1625 else
1626 abort ();
1627}
1628
1629/* Nonzero if a compare of mode MODE can be done straightforwardly
1630 (without splitting it into pieces). */
1631
1632int
1633can_compare_p (mode)
1634 enum machine_mode mode;
1635{
1636 do
1637 {
1638 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1639 return 1;
1640 mode = GET_MODE_WIDER_MODE (mode);
1641 } while (mode != VOIDmode);
1642
1643 return 0;
1644}
1645\f
1646/* Emit a library call comparison between floating point X and Y.
1647 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1648
1649static void
1650emit_float_lib_cmp (x, y, comparison)
1651 rtx x, y;
1652 enum rtx_code comparison;
1653{
1654 enum machine_mode mode = GET_MODE (x);
1655 rtx libfunc;
1656
1657 if (mode == SFmode)
1658 switch (comparison)
1659 {
1660 case EQ:
1661 libfunc = eqsf2_libfunc;
1662 break;
1663
1664 case NE:
1665 libfunc = nesf2_libfunc;
1666 break;
1667
1668 case GT:
1669 libfunc = gtsf2_libfunc;
1670 break;
1671
1672 case GE:
1673 libfunc = gesf2_libfunc;
1674 break;
1675
1676 case LT:
1677 libfunc = ltsf2_libfunc;
1678 break;
1679
1680 case LE:
1681 libfunc = lesf2_libfunc;
1682 break;
1683 }
1684 else if (mode == DFmode)
1685 switch (comparison)
1686 {
1687 case EQ:
1688 libfunc = eqdf2_libfunc;
1689 break;
1690
1691 case NE:
1692 libfunc = nedf2_libfunc;
1693 break;
1694
1695 case GT:
1696 libfunc = gtdf2_libfunc;
1697 break;
1698
1699 case GE:
1700 libfunc = gedf2_libfunc;
1701 break;
1702
1703 case LT:
1704 libfunc = ltdf2_libfunc;
1705 break;
1706
1707 case LE:
1708 libfunc = ledf2_libfunc;
1709 break;
1710 }
1711 else
1712 {
1713 enum machine_mode wider_mode;
1714
34e56753 1715 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1716 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1717 {
1718 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1719 != CODE_FOR_nothing)
1720 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1721 {
1722 x = convert_to_mode (wider_mode, x, 0);
1723 y = convert_to_mode (wider_mode, y, 0);
1724 emit_float_lib_cmp (x, y, comparison);
1725 return;
1726 }
1727 }
1728 abort ();
1729 }
1730
86f8eff3 1731 emit_library_call (libfunc, 1,
77c9c6c2
RK
1732 SImode, 2, x, mode, y, mode);
1733
1734 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1735 0, SImode, 0, 0);
1736}
1737\f
1738/* Generate code to indirectly jump to a location given in the rtx LOC. */
1739
1740void
1741emit_indirect_jump (loc)
1742 rtx loc;
1743{
1744 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1745 (loc, VOIDmode)))
1746 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1747 loc);
1748
1749 emit_jump_insn (gen_indirect_jump (loc));
1750}
1751\f
1752/* These three functions generate an insn body and return it
1753 rather than emitting the insn.
1754
1755 They do not protect from queued increments,
1756 because they may be used 1) in protect_from_queue itself
1757 and 2) in other passes where there is no queue. */
1758
1759/* Generate and return an insn body to add Y to X. */
1760
1761rtx
1762gen_add2_insn (x, y)
1763 rtx x, y;
1764{
1765 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1766
1767 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1768 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1769 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1770 abort ();
1771
1772 return (GEN_FCN (icode) (x, x, y));
1773}
1774
1775int
1776have_add2_insn (mode)
1777 enum machine_mode mode;
1778{
1779 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1780}
1781
1782/* Generate and return an insn body to subtract Y from X. */
1783
1784rtx
1785gen_sub2_insn (x, y)
1786 rtx x, y;
1787{
1788 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1789
1790 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1791 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1792 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1793 abort ();
1794
1795 return (GEN_FCN (icode) (x, x, y));
1796}
1797
1798int
1799have_sub2_insn (mode)
1800 enum machine_mode mode;
1801{
1802 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1803}
1804
1805/* Generate the body of an instruction to copy Y into X. */
1806
1807rtx
1808gen_move_insn (x, y)
1809 rtx x, y;
1810{
1811 register enum machine_mode mode = GET_MODE (x);
1812 enum insn_code insn_code;
1813
1814 if (mode == VOIDmode)
1815 mode = GET_MODE (y);
1816
1817 insn_code = mov_optab->handlers[(int) mode].insn_code;
1818
1819 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1820 find a mode to do it in. If we have a movcc, use it. Otherwise,
1821 find the MODE_INT mode of the same width. */
1822
1823 if (insn_code == CODE_FOR_nothing)
1824 {
1825 enum machine_mode tmode = VOIDmode;
1826 rtx x1 = x, y1 = y;
1827
1828 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1829 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1830 tmode = CCmode;
1831 else if (GET_MODE_CLASS (mode) == MODE_CC)
1832 for (tmode = QImode; tmode != VOIDmode;
1833 tmode = GET_MODE_WIDER_MODE (tmode))
1834 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1835 break;
1836
1837 if (tmode == VOIDmode)
1838 abort ();
1839
1840 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1841 may call change_address which is not appropriate if we were
1842 called when a reload was in progress. We don't have to worry
1843 about changing the address since the size in bytes is supposed to
1844 be the same. Copy the MEM to change the mode and move any
1845 substitutions from the old MEM to the new one. */
1846
1847 if (reload_in_progress)
1848 {
1849 x = gen_lowpart_common (tmode, x1);
1850 if (x == 0 && GET_CODE (x1) == MEM)
1851 {
1852 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1853 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1854 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1855 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1856 copy_replacements (x1, x);
1857 }
1858
1859 y = gen_lowpart_common (tmode, y1);
1860 if (y == 0 && GET_CODE (y1) == MEM)
1861 {
1862 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1863 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1864 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1865 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1866 copy_replacements (y1, y);
1867 }
1868 }
1869 else
1870 {
1871 x = gen_lowpart (tmode, x);
1872 y = gen_lowpart (tmode, y);
1873 }
1874
1875 insn_code = mov_optab->handlers[(int) tmode].insn_code;
1876 }
1877
1878 return (GEN_FCN (insn_code) (x, y));
1879}
1880\f
1881/* Tables of patterns for extending one integer mode to another. */
34e56753 1882static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
77c9c6c2 1883
34e56753
RS
1884/* Return the insn code used to extend FROM_MODE to TO_MODE.
1885 UNSIGNEDP specifies zero-extension instead of sign-extension. If
1886 no such operation exists, CODE_FOR_nothing will be returned. */
77c9c6c2 1887
34e56753 1888enum insn_code
77c9c6c2
RK
1889can_extend_p (to_mode, from_mode, unsignedp)
1890 enum machine_mode to_mode, from_mode;
1891 int unsignedp;
1892{
34e56753 1893 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
77c9c6c2
RK
1894}
1895
1896/* Generate the body of an insn to extend Y (with mode MFROM)
1897 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
1898
1899rtx
1900gen_extend_insn (x, y, mto, mfrom, unsignedp)
1901 rtx x, y;
1902 enum machine_mode mto, mfrom;
1903 int unsignedp;
1904{
34e56753 1905 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
77c9c6c2
RK
1906}
1907
1908static void
1909init_extends ()
1910{
34e56753
RS
1911 enum insn_code *p;
1912
1913 for (p = extendtab[0][0];
1914 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
1915 p++)
1916 *p = CODE_FOR_nothing;
77c9c6c2
RK
1917
1918#ifdef HAVE_extendditi2
1919 if (HAVE_extendditi2)
34e56753 1920 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
77c9c6c2
RK
1921#endif
1922#ifdef HAVE_extendsiti2
1923 if (HAVE_extendsiti2)
34e56753 1924 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
77c9c6c2
RK
1925#endif
1926#ifdef HAVE_extendhiti2
1927 if (HAVE_extendhiti2)
34e56753 1928 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
77c9c6c2
RK
1929#endif
1930#ifdef HAVE_extendqiti2
1931 if (HAVE_extendqiti2)
34e56753 1932 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
77c9c6c2
RK
1933#endif
1934#ifdef HAVE_extendsidi2
1935 if (HAVE_extendsidi2)
34e56753 1936 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
77c9c6c2
RK
1937#endif
1938#ifdef HAVE_extendhidi2
1939 if (HAVE_extendhidi2)
34e56753 1940 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
77c9c6c2
RK
1941#endif
1942#ifdef HAVE_extendqidi2
1943 if (HAVE_extendqidi2)
34e56753 1944 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
77c9c6c2
RK
1945#endif
1946#ifdef HAVE_extendhisi2
1947 if (HAVE_extendhisi2)
34e56753 1948 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
77c9c6c2
RK
1949#endif
1950#ifdef HAVE_extendqisi2
1951 if (HAVE_extendqisi2)
34e56753 1952 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
77c9c6c2
RK
1953#endif
1954#ifdef HAVE_extendqihi2
1955 if (HAVE_extendqihi2)
34e56753 1956 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
77c9c6c2
RK
1957#endif
1958
1959#ifdef HAVE_zero_extendditi2
1960 if (HAVE_zero_extendsiti2)
34e56753 1961 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
77c9c6c2
RK
1962#endif
1963#ifdef HAVE_zero_extendsiti2
1964 if (HAVE_zero_extendsiti2)
34e56753 1965 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
77c9c6c2
RK
1966#endif
1967#ifdef HAVE_zero_extendhiti2
1968 if (HAVE_zero_extendhiti2)
34e56753 1969 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
77c9c6c2
RK
1970#endif
1971#ifdef HAVE_zero_extendqiti2
1972 if (HAVE_zero_extendqiti2)
34e56753 1973 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
77c9c6c2
RK
1974#endif
1975#ifdef HAVE_zero_extendsidi2
1976 if (HAVE_zero_extendsidi2)
34e56753 1977 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
77c9c6c2
RK
1978#endif
1979#ifdef HAVE_zero_extendhidi2
1980 if (HAVE_zero_extendhidi2)
34e56753 1981 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
77c9c6c2
RK
1982#endif
1983#ifdef HAVE_zero_extendqidi2
1984 if (HAVE_zero_extendqidi2)
34e56753 1985 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
77c9c6c2
RK
1986#endif
1987#ifdef HAVE_zero_extendhisi2
1988 if (HAVE_zero_extendhisi2)
34e56753 1989 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
77c9c6c2
RK
1990#endif
1991#ifdef HAVE_zero_extendqisi2
1992 if (HAVE_zero_extendqisi2)
34e56753 1993 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
77c9c6c2
RK
1994#endif
1995#ifdef HAVE_zero_extendqihi2
1996 if (HAVE_zero_extendqihi2)
34e56753 1997 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
77c9c6c2
RK
1998#endif
1999}
2000\f
2001/* can_fix_p and can_float_p say whether the target machine
2002 can directly convert a given fixed point type to
2003 a given floating point type, or vice versa.
2004 The returned value is the CODE_FOR_... value to use,
2005 or CODE_FOR_nothing if these modes cannot be directly converted. */
2006
2007static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2008static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2009static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2010
2011/* *TRUNCP_PTR is set to 1 if it is necessary to output
2012 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2013
2014static enum insn_code
2015can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2016 enum machine_mode fltmode, fixmode;
2017 int unsignedp;
2018 int *truncp_ptr;
2019{
2020 *truncp_ptr = 0;
2021 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2022 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2023
2024 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2025 {
2026 *truncp_ptr = 1;
2027 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2028 }
2029 return CODE_FOR_nothing;
2030}
2031
2032static enum insn_code
2033can_float_p (fltmode, fixmode, unsignedp)
2034 enum machine_mode fixmode, fltmode;
2035 int unsignedp;
2036{
2037 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2038}
2039
2040void
2041init_fixtab ()
2042{
2043 enum insn_code *p;
2044 for (p = fixtab[0][0];
2045 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2046 p++)
2047 *p = CODE_FOR_nothing;
2048 for (p = fixtrunctab[0][0];
2049 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2050 p++)
2051 *p = CODE_FOR_nothing;
2052
2053#ifdef HAVE_fixsfqi2
2054 if (HAVE_fixsfqi2)
2055 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2056#endif
2057#ifdef HAVE_fixsfhi2
2058 if (HAVE_fixsfhi2)
2059 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2060#endif
2061#ifdef HAVE_fixsfsi2
2062 if (HAVE_fixsfsi2)
2063 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2064#endif
2065#ifdef HAVE_fixsfdi2
2066 if (HAVE_fixsfdi2)
2067 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2068#endif
2069
2070#ifdef HAVE_fixdfqi2
2071 if (HAVE_fixdfqi2)
2072 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2073#endif
2074#ifdef HAVE_fixdfhi2
2075 if (HAVE_fixdfhi2)
2076 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2077#endif
2078#ifdef HAVE_fixdfsi2
2079 if (HAVE_fixdfsi2)
2080 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2081#endif
2082#ifdef HAVE_fixdfdi2
2083 if (HAVE_fixdfdi2)
2084 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2085#endif
2086#ifdef HAVE_fixdfti2
2087 if (HAVE_fixdfti2)
2088 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2089#endif
2090
2091#ifdef HAVE_fixtfqi2
2092 if (HAVE_fixtfqi2)
2093 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2094#endif
2095#ifdef HAVE_fixtfhi2
2096 if (HAVE_fixtfhi2)
2097 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2098#endif
2099#ifdef HAVE_fixtfsi2
2100 if (HAVE_fixtfsi2)
2101 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2102#endif
2103#ifdef HAVE_fixtfdi2
2104 if (HAVE_fixtfdi2)
2105 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2106#endif
2107#ifdef HAVE_fixtfti2
2108 if (HAVE_fixtfti2)
2109 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2110#endif
2111
2112#ifdef HAVE_fixunssfqi2
2113 if (HAVE_fixunssfqi2)
2114 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2115#endif
2116#ifdef HAVE_fixunssfhi2
2117 if (HAVE_fixunssfhi2)
2118 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2119#endif
2120#ifdef HAVE_fixunssfsi2
2121 if (HAVE_fixunssfsi2)
2122 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2123#endif
2124#ifdef HAVE_fixunssfdi2
2125 if (HAVE_fixunssfdi2)
2126 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2127#endif
2128
2129#ifdef HAVE_fixunsdfqi2
2130 if (HAVE_fixunsdfqi2)
2131 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2132#endif
2133#ifdef HAVE_fixunsdfhi2
2134 if (HAVE_fixunsdfhi2)
2135 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2136#endif
2137#ifdef HAVE_fixunsdfsi2
2138 if (HAVE_fixunsdfsi2)
2139 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2140#endif
2141#ifdef HAVE_fixunsdfdi2
2142 if (HAVE_fixunsdfdi2)
2143 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2144#endif
2145#ifdef HAVE_fixunsdfti2
2146 if (HAVE_fixunsdfti2)
2147 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2148#endif
2149
2150#ifdef HAVE_fixunstfqi2
2151 if (HAVE_fixunstfqi2)
2152 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2153#endif
2154#ifdef HAVE_fixunstfhi2
2155 if (HAVE_fixunstfhi2)
2156 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2157#endif
2158#ifdef HAVE_fixunstfsi2
2159 if (HAVE_fixunstfsi2)
2160 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2161#endif
2162#ifdef HAVE_fixunstfdi2
2163 if (HAVE_fixunstfdi2)
2164 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2165#endif
2166#ifdef HAVE_fixunstfti2
2167 if (HAVE_fixunstfti2)
2168 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2169#endif
2170
2171#ifdef HAVE_fix_truncsfqi2
2172 if (HAVE_fix_truncsfqi2)
2173 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2174#endif
2175#ifdef HAVE_fix_truncsfhi2
2176 if (HAVE_fix_truncsfhi2)
2177 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2178#endif
2179#ifdef HAVE_fix_truncsfsi2
2180 if (HAVE_fix_truncsfsi2)
2181 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2182#endif
2183#ifdef HAVE_fix_truncsfdi2
2184 if (HAVE_fix_truncsfdi2)
2185 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2186#endif
2187
2188#ifdef HAVE_fix_truncdfqi2
2189 if (HAVE_fix_truncdfsi2)
2190 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2191#endif
2192#ifdef HAVE_fix_truncdfhi2
2193 if (HAVE_fix_truncdfhi2)
2194 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2195#endif
2196#ifdef HAVE_fix_truncdfsi2
2197 if (HAVE_fix_truncdfsi2)
2198 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2199#endif
2200#ifdef HAVE_fix_truncdfdi2
2201 if (HAVE_fix_truncdfdi2)
2202 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2203#endif
2204#ifdef HAVE_fix_truncdfti2
2205 if (HAVE_fix_truncdfti2)
2206 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2207#endif
2208
2209#ifdef HAVE_fix_trunctfqi2
2210 if (HAVE_fix_trunctfqi2)
2211 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2212#endif
2213#ifdef HAVE_fix_trunctfhi2
2214 if (HAVE_fix_trunctfhi2)
2215 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2216#endif
2217#ifdef HAVE_fix_trunctfsi2
2218 if (HAVE_fix_trunctfsi2)
2219 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2220#endif
2221#ifdef HAVE_fix_trunctfdi2
2222 if (HAVE_fix_trunctfdi2)
2223 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2224#endif
2225#ifdef HAVE_fix_trunctfti2
2226 if (HAVE_fix_trunctfti2)
2227 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2228#endif
2229
2230#ifdef HAVE_fixuns_truncsfqi2
2231 if (HAVE_fixuns_truncsfqi2)
2232 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2233#endif
2234#ifdef HAVE_fixuns_truncsfhi2
2235 if (HAVE_fixuns_truncsfhi2)
2236 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2237#endif
2238#ifdef HAVE_fixuns_truncsfsi2
2239 if (HAVE_fixuns_truncsfsi2)
2240 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2241#endif
2242#ifdef HAVE_fixuns_truncsfdi2
2243 if (HAVE_fixuns_truncsfdi2)
2244 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2245#endif
2246
2247#ifdef HAVE_fixuns_truncdfqi2
2248 if (HAVE_fixuns_truncdfqi2)
2249 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2250#endif
2251#ifdef HAVE_fixuns_truncdfhi2
2252 if (HAVE_fixuns_truncdfhi2)
2253 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2254#endif
2255#ifdef HAVE_fixuns_truncdfsi2
2256 if (HAVE_fixuns_truncdfsi2)
2257 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2258#endif
2259#ifdef HAVE_fixuns_truncdfdi2
2260 if (HAVE_fixuns_truncdfdi2)
2261 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2262#endif
2263#ifdef HAVE_fixuns_truncdfti2
2264 if (HAVE_fixuns_truncdfti2)
2265 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2266#endif
2267
2268#ifdef HAVE_fixuns_trunctfqi2
2269 if (HAVE_fixuns_trunctfqi2)
2270 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2271#endif
2272#ifdef HAVE_fixuns_trunctfhi2
2273 if (HAVE_fixuns_trunctfhi2)
2274 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2275#endif
2276#ifdef HAVE_fixuns_trunctfsi2
2277 if (HAVE_fixuns_trunctfsi2)
2278 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2279#endif
2280#ifdef HAVE_fixuns_trunctfdi2
2281 if (HAVE_fixuns_trunctfdi2)
2282 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2283#endif
2284#ifdef HAVE_fixuns_trunctfti2
2285 if (HAVE_fixuns_trunctfti2)
2286 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2287#endif
2288
2289#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2290 /* This flag says the same insns that convert to a signed fixnum
2291 also convert validly to an unsigned one. */
2292 {
2293 int i;
2294 int j;
2295 for (i = 0; i < NUM_MACHINE_MODES; i++)
2296 for (j = 0; j < NUM_MACHINE_MODES; j++)
2297 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2298 }
2299#endif
2300}
2301
2302void
2303init_floattab ()
2304{
2305 enum insn_code *p;
2306 for (p = floattab[0][0];
2307 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2308 p++)
2309 *p = CODE_FOR_nothing;
2310
2311#ifdef HAVE_floatqisf2
2312 if (HAVE_floatqisf2)
2313 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2314#endif
2315#ifdef HAVE_floathisf2
2316 if (HAVE_floathisf2)
2317 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2318#endif
2319#ifdef HAVE_floatsisf2
2320 if (HAVE_floatsisf2)
2321 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2322#endif
2323#ifdef HAVE_floatdisf2
2324 if (HAVE_floatdisf2)
2325 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2326#endif
2327#ifdef HAVE_floattisf2
2328 if (HAVE_floattisf2)
2329 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2330#endif
2331
2332#ifdef HAVE_floatqidf2
2333 if (HAVE_floatqidf2)
2334 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2335#endif
2336#ifdef HAVE_floathidf2
2337 if (HAVE_floathidf2)
2338 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2339#endif
2340#ifdef HAVE_floatsidf2
2341 if (HAVE_floatsidf2)
2342 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2343#endif
2344#ifdef HAVE_floatdidf2
2345 if (HAVE_floatdidf2)
2346 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2347#endif
2348#ifdef HAVE_floattidf2
2349 if (HAVE_floattidf2)
2350 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2351#endif
2352
2353#ifdef HAVE_floatqitf2
2354 if (HAVE_floatqitf2)
2355 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2356#endif
2357#ifdef HAVE_floathitf2
2358 if (HAVE_floathitf2)
2359 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2360#endif
2361#ifdef HAVE_floatsitf2
2362 if (HAVE_floatsitf2)
2363 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2364#endif
2365#ifdef HAVE_floatditf2
2366 if (HAVE_floatditf2)
2367 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2368#endif
2369#ifdef HAVE_floattitf2
2370 if (HAVE_floattitf2)
2371 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2372#endif
2373
2374#ifdef HAVE_floatunsqisf2
2375 if (HAVE_floatunsqisf2)
2376 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2377#endif
2378#ifdef HAVE_floatunshisf2
2379 if (HAVE_floatunshisf2)
2380 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2381#endif
2382#ifdef HAVE_floatunssisf2
2383 if (HAVE_floatunssisf2)
2384 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2385#endif
2386#ifdef HAVE_floatunsdisf2
2387 if (HAVE_floatunsdisf2)
2388 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2389#endif
2390#ifdef HAVE_floatunstisf2
2391 if (HAVE_floatunstisf2)
2392 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2393#endif
2394
2395#ifdef HAVE_floatunsqidf2
2396 if (HAVE_floatunsqidf2)
2397 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2398#endif
2399#ifdef HAVE_floatunshidf2
2400 if (HAVE_floatunshidf2)
2401 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2402#endif
2403#ifdef HAVE_floatunssidf2
2404 if (HAVE_floatunssidf2)
2405 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2406#endif
2407#ifdef HAVE_floatunsdidf2
2408 if (HAVE_floatunsdidf2)
2409 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2410#endif
2411#ifdef HAVE_floatunstidf2
2412 if (HAVE_floatunstidf2)
2413 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2414#endif
2415
2416#ifdef HAVE_floatunsqitf2
2417 if (HAVE_floatunsqitf2)
2418 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2419#endif
2420#ifdef HAVE_floatunshitf2
2421 if (HAVE_floatunshitf2)
2422 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2423#endif
2424#ifdef HAVE_floatunssitf2
2425 if (HAVE_floatunssitf2)
2426 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2427#endif
2428#ifdef HAVE_floatunsditf2
2429 if (HAVE_floatunsditf2)
2430 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2431#endif
2432#ifdef HAVE_floatunstitf2
2433 if (HAVE_floatunstitf2)
2434 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2435#endif
2436}
2437\f
2438/* Generate code to convert FROM to floating point
34e56753 2439 and store in TO. FROM must be fixed point and not VOIDmode.
77c9c6c2
RK
2440 UNSIGNEDP nonzero means regard FROM as unsigned.
2441 Normally this is done by correcting the final value
2442 if it is negative. */
2443
2444void
2445expand_float (to, from, unsignedp)
2446 rtx to, from;
2447 int unsignedp;
2448{
2449 enum insn_code icode;
2450 register rtx target = to;
2451 enum machine_mode fmode, imode;
2452
34e56753
RS
2453 /* Crash now, because we won't be able to decide which mode to use. */
2454 if (GET_MODE (from) == VOIDmode)
2455 abort ();
2456
77c9c6c2
RK
2457 /* Look for an insn to do the conversion. Do it in the specified
2458 modes if possible; otherwise convert either input, output or both to
2459 wider mode. If the integer mode is wider than the mode of FROM,
2460 we can do the conversion signed even if the input is unsigned. */
2461
2462 for (imode = GET_MODE (from); imode != VOIDmode;
2463 imode = GET_MODE_WIDER_MODE (imode))
2464 for (fmode = GET_MODE (to); fmode != VOIDmode;
2465 fmode = GET_MODE_WIDER_MODE (fmode))
2466 {
2467 int doing_unsigned = unsignedp;
2468
2469 icode = can_float_p (fmode, imode, unsignedp);
2470 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2471 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2472
2473 if (icode != CODE_FOR_nothing)
2474 {
2475 to = protect_from_queue (to, 1);
2476
2477 if (imode != GET_MODE (from))
2478 from = convert_to_mode (imode, from, unsignedp);
2479 else
2480 from = protect_from_queue (from, 0);
2481
2482 if (fmode != GET_MODE (to))
2483 target = gen_reg_rtx (fmode);
2484
2485 emit_unop_insn (icode, target, from,
2486 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2487
2488 if (target != to)
2489 convert_move (to, target, 0);
2490 return;
2491 }
2492 }
2493
2494#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2495
2496 /* Unsigned integer, and no way to convert directly.
2497 Convert as signed, then conditionally adjust the result. */
2498 if (unsignedp)
2499 {
2500 rtx label = gen_label_rtx ();
2501 rtx temp;
2502 REAL_VALUE_TYPE offset;
2503
2504 emit_queue ();
2505
2506 to = protect_from_queue (to, 1);
2507 from = protect_from_queue (from, 0);
2508
2509 if (flag_force_mem)
2510 from = force_not_mem (from);
2511
2512 /* If we are about to do some arithmetic to correct for an
2513 unsigned operand, do it in a pseudo-register. */
2514
2515 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2516 target = gen_reg_rtx (GET_MODE (to));
2517
2518 /* Convert as signed integer to floating. */
2519 expand_float (target, from, 0);
2520
2521 /* If FROM is negative (and therefore TO is negative),
2522 correct its value by 2**bitwidth. */
2523
2524 do_pending_stack_adjust ();
2525 emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2526 emit_jump_insn (gen_bge (label));
2527 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2528 Rather than setting up a dconst_dot_5, let's hope SCO
2529 fixes the bug. */
2530 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2531 temp = expand_binop (GET_MODE (to), add_optab, target,
2532 immed_real_const_1 (offset, GET_MODE (to)),
2533 target, 0, OPTAB_LIB_WIDEN);
2534 if (temp != target)
2535 emit_move_insn (target, temp);
2536 do_pending_stack_adjust ();
2537 emit_label (label);
2538 }
2539 else
2540#endif
2541
2542 /* No hardware instruction available; call a library
2543 to convert from SImode or DImode into SFmode or DFmode. */
2544 {
6bce1b78 2545 rtx libfcn;
77c9c6c2
RK
2546 rtx insns;
2547
2548 to = protect_from_queue (to, 1);
2549
2550 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2551 from = convert_to_mode (SImode, from, unsignedp);
2552 else
2553 from = protect_from_queue (from, 0);
2554
2555 if (flag_force_mem)
2556 from = force_not_mem (from);
2557
2558 if (GET_MODE (to) == SFmode)
2559 {
2560 if (GET_MODE (from) == SImode)
6bce1b78 2561 libfcn = floatsisf_libfunc;
77c9c6c2 2562 else if (GET_MODE (from) == DImode)
6bce1b78 2563 libfcn = floatdisf_libfunc;
77c9c6c2
RK
2564 else
2565 abort ();
2566 }
2567 else if (GET_MODE (to) == DFmode)
2568 {
2569 if (GET_MODE (from) == SImode)
6bce1b78 2570 libfcn = floatsidf_libfunc;
77c9c6c2 2571 else if (GET_MODE (from) == DImode)
6bce1b78 2572 libfcn = floatdidf_libfunc;
77c9c6c2
RK
2573 else
2574 abort ();
2575 }
2576 else
2577 abort ();
2578
2579 start_sequence ();
2580
86f8eff3 2581 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
2582 insns = get_insns ();
2583 end_sequence ();
2584
2585 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2586 gen_rtx (FLOAT, GET_MODE (to), from));
2587 }
2588
2589 /* Copy result to requested destination
2590 if we have been computing in a temp location. */
2591
2592 if (target != to)
2593 {
2594 if (GET_MODE (target) == GET_MODE (to))
2595 emit_move_insn (to, target);
2596 else
2597 convert_move (to, target, 0);
2598 }
2599}
2600\f
2601/* expand_fix: generate code to convert FROM to fixed point
2602 and store in TO. FROM must be floating point. */
2603
2604static rtx
2605ftruncify (x)
2606 rtx x;
2607{
2608 rtx temp = gen_reg_rtx (GET_MODE (x));
2609 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2610}
2611
2612void
2613expand_fix (to, from, unsignedp)
2614 register rtx to, from;
2615 int unsignedp;
2616{
2617 enum insn_code icode;
2618 register rtx target = to;
2619 enum machine_mode fmode, imode;
2620 int must_trunc = 0;
6bce1b78 2621 rtx libfcn = 0;
77c9c6c2
RK
2622
2623 /* We first try to find a pair of modes, one real and one integer, at
2624 least as wide as FROM and TO, respectively, in which we can open-code
2625 this conversion. If the integer mode is wider than the mode of TO,
2626 we can do the conversion either signed or unsigned. */
2627
2628 for (imode = GET_MODE (to); imode != VOIDmode;
2629 imode = GET_MODE_WIDER_MODE (imode))
2630 for (fmode = GET_MODE (from); fmode != VOIDmode;
2631 fmode = GET_MODE_WIDER_MODE (fmode))
2632 {
2633 int doing_unsigned = unsignedp;
2634
2635 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2636 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2637 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2638
2639 if (icode != CODE_FOR_nothing)
2640 {
2641 to = protect_from_queue (to, 1);
2642
2643 if (fmode != GET_MODE (from))
2644 from = convert_to_mode (fmode, from, 0);
2645 else
2646 from = protect_from_queue (from, 0);
2647
2648 if (must_trunc)
2649 from = ftruncify (from);
2650
2651 if (imode != GET_MODE (to))
2652 target = gen_reg_rtx (imode);
2653
2654 emit_unop_insn (icode, target, from,
2655 doing_unsigned ? UNSIGNED_FIX : FIX);
2656 if (target != to)
2657 convert_move (to, target, unsignedp);
2658 return;
2659 }
2660 }
2661
2662#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2663 /* For an unsigned conversion, there is one more way to do it.
2664 If we have a signed conversion, we generate code that compares
2665 the real value to the largest representable positive number. If if
2666 is smaller, the conversion is done normally. Otherwise, subtract
2667 one plus the highest signed number, convert, and add it back.
2668
2669 We only need to check all real modes, since we know we didn't find
2670 anything with a wider inetger mode. */
2671
2672 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2673 for (fmode = GET_MODE (from); fmode != VOIDmode;
2674 fmode = GET_MODE_WIDER_MODE (fmode))
2675 /* Make sure we won't lose significant bits doing this. */
2676 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2677 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2678 &must_trunc))
2679 {
2680 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2681 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2682 rtx limit = immed_real_const_1 (offset, fmode);
2683 rtx lab1 = gen_label_rtx ();
2684 rtx lab2 = gen_label_rtx ();
2685 rtx insn;
2686
2687 emit_queue ();
2688 to = protect_from_queue (to, 1);
2689 from = protect_from_queue (from, 0);
2690
2691 if (flag_force_mem)
2692 from = force_not_mem (from);
2693
2694 if (fmode != GET_MODE (from))
2695 from = convert_to_mode (fmode, from, 0);
2696
2697 /* See if we need to do the subtraction. */
2698 do_pending_stack_adjust ();
2699 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2700 emit_jump_insn (gen_bge (lab1));
2701
2702 /* If not, do the signed "fix" and branch around fixup code. */
2703 expand_fix (to, from, 0);
2704 emit_jump_insn (gen_jump (lab2));
2705 emit_barrier ();
2706
2707 /* Otherwise, subtract 2**(N-1), convert to signed number,
2708 then add 2**(N-1). Do the addition using XOR since this
2709 will often generate better code. */
2710 emit_label (lab1);
2711 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2712 0, 0, OPTAB_LIB_WIDEN);
2713 expand_fix (to, target, 0);
2714 target = expand_binop (GET_MODE (to), xor_optab, to,
2715 gen_rtx (CONST_INT, VOIDmode,
2716 1 << (bitsize - 1)),
2717 to, 1, OPTAB_LIB_WIDEN);
2718
2719 if (target != to)
2720 emit_move_insn (to, target);
2721
2722 emit_label (lab2);
2723
2724 /* Make a place for a REG_NOTE and add it. */
2725 insn = emit_move_insn (to, to);
2726 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2727 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2728 from), REG_NOTES (insn));
2729
2730 return;
2731 }
2732#endif
2733
2734 /* We can't do it with an insn, so use a library call. But first ensure
2735 that the mode of TO is at least as wide as SImode, since those are the
2736 only library calls we know about. */
2737
2738 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
2739 {
2740 target = gen_reg_rtx (SImode);
2741
2742 expand_fix (target, from, unsignedp);
2743 }
2744 else if (GET_MODE (from) == SFmode)
2745 {
2746 if (GET_MODE (to) == SImode)
6bce1b78 2747 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
77c9c6c2 2748 else if (GET_MODE (to) == DImode)
6bce1b78 2749 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
77c9c6c2
RK
2750 else
2751 abort ();
2752 }
2753 else if (GET_MODE (from) == DFmode)
2754 {
2755 if (GET_MODE (to) == SImode)
6bce1b78 2756 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
77c9c6c2 2757 else if (GET_MODE (to) == DImode)
6bce1b78 2758 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
77c9c6c2
RK
2759 else
2760 abort ();
2761 }
2762 else
2763 abort ();
2764
6bce1b78 2765 if (libfcn)
77c9c6c2
RK
2766 {
2767 rtx insns;
2768
2769 to = protect_from_queue (to, 1);
2770 from = protect_from_queue (from, 0);
2771
2772 if (flag_force_mem)
2773 from = force_not_mem (from);
2774
2775 start_sequence ();
2776
86f8eff3 2777 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
77c9c6c2
RK
2778 insns = get_insns ();
2779 end_sequence ();
2780
2781 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2782 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
2783 GET_MODE (to), from));
2784 }
2785
2786 if (GET_MODE (to) == GET_MODE (target))
2787 emit_move_insn (to, target);
2788 else
2789 convert_move (to, target, 0);
2790}
2791\f
2792static optab
2793init_optab (code)
2794 enum rtx_code code;
2795{
2796 int i;
2797 optab op = (optab) xmalloc (sizeof (struct optab));
2798 op->code = code;
2799 for (i = 0; i < NUM_MACHINE_MODES; i++)
2800 {
2801 op->handlers[i].insn_code = CODE_FOR_nothing;
2802 op->handlers[i].libfunc = 0;
2803 }
2804 return op;
2805}
2806
2807/* Call this once to initialize the contents of the optabs
2808 appropriately for the current target machine. */
2809
2810void
2811init_optabs ()
2812{
2813 int i;
2814
2815 init_fixtab ();
2816 init_floattab ();
2817 init_extends ();
2818
2819 add_optab = init_optab (PLUS);
2820 sub_optab = init_optab (MINUS);
2821 smul_optab = init_optab (MULT);
2822 smul_widen_optab = init_optab (UNKNOWN);
2823 umul_widen_optab = init_optab (UNKNOWN);
2824 sdiv_optab = init_optab (DIV);
2825 sdivmod_optab = init_optab (UNKNOWN);
2826 udiv_optab = init_optab (UDIV);
2827 udivmod_optab = init_optab (UNKNOWN);
2828 smod_optab = init_optab (MOD);
2829 umod_optab = init_optab (UMOD);
2830 flodiv_optab = init_optab (DIV);
2831 ftrunc_optab = init_optab (UNKNOWN);
2832 and_optab = init_optab (AND);
2833 ior_optab = init_optab (IOR);
2834 xor_optab = init_optab (XOR);
2835 ashl_optab = init_optab (ASHIFT);
2836 ashr_optab = init_optab (ASHIFTRT);
2837 lshl_optab = init_optab (LSHIFT);
2838 lshr_optab = init_optab (LSHIFTRT);
2839 rotl_optab = init_optab (ROTATE);
2840 rotr_optab = init_optab (ROTATERT);
2841 smin_optab = init_optab (SMIN);
2842 smax_optab = init_optab (SMAX);
2843 umin_optab = init_optab (UMIN);
2844 umax_optab = init_optab (UMAX);
2845 mov_optab = init_optab (UNKNOWN);
2846 movstrict_optab = init_optab (UNKNOWN);
2847 cmp_optab = init_optab (UNKNOWN);
2848 ucmp_optab = init_optab (UNKNOWN);
2849 tst_optab = init_optab (UNKNOWN);
2850 neg_optab = init_optab (NEG);
2851 abs_optab = init_optab (ABS);
2852 one_cmpl_optab = init_optab (NOT);
2853 ffs_optab = init_optab (FFS);
d45cf215 2854 sqrt_optab = init_optab (SQRT);
19c3fc24 2855 strlen_optab = init_optab (UNKNOWN);
77c9c6c2
RK
2856
2857#ifdef HAVE_addqi3
2858 if (HAVE_addqi3)
2859 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
2860#endif
2861#ifdef HAVE_addhi3
2862 if (HAVE_addhi3)
2863 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
2864#endif
2865#ifdef HAVE_addpsi3
2866 if (HAVE_addpsi3)
2867 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
2868#endif
2869#ifdef HAVE_addsi3
2870 if (HAVE_addsi3)
2871 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
2872#endif
2873#ifdef HAVE_adddi3
2874 if (HAVE_adddi3)
2875 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
2876#endif
2877#ifdef HAVE_addti3
2878 if (HAVE_addti3)
2879 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
2880#endif
2881#ifdef HAVE_addsf3
2882 if (HAVE_addsf3)
2883 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
2884#endif
2885#ifdef HAVE_adddf3
2886 if (HAVE_adddf3)
2887 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
2888#endif
2889#ifdef HAVE_addtf3
2890 if (HAVE_addtf3)
2891 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
2892#endif
2893 add_optab->handlers[(int) SFmode].libfunc
2894 = gen_rtx (SYMBOL_REF, Pmode, "__addsf3");
2895 add_optab->handlers[(int) DFmode].libfunc
2896 = gen_rtx (SYMBOL_REF, Pmode, "__adddf3");
2897
2898#ifdef HAVE_subqi3
2899 if (HAVE_subqi3)
2900 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
2901#endif
2902#ifdef HAVE_subhi3
2903 if (HAVE_subhi3)
2904 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
2905#endif
2906#ifdef HAVE_subpsi3
2907 if (HAVE_subpsi3)
2908 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
2909#endif
2910#ifdef HAVE_subsi3
2911 if (HAVE_subsi3)
2912 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
2913#endif
2914#ifdef HAVE_subdi3
2915 if (HAVE_subdi3)
2916 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
2917#endif
2918#ifdef HAVE_subti3
2919 if (HAVE_subti3)
ded40dfe 2920 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
77c9c6c2
RK
2921#endif
2922#ifdef HAVE_subsf3
2923 if (HAVE_subsf3)
2924 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
2925#endif
2926#ifdef HAVE_subdf3
2927 if (HAVE_subdf3)
2928 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
2929#endif
2930#ifdef HAVE_subtf3
2931 if (HAVE_subtf3)
2932 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
2933#endif
2934 sub_optab->handlers[(int) SFmode].libfunc
2935 = gen_rtx (SYMBOL_REF, Pmode, "__subsf3");
2936 sub_optab->handlers[(int) DFmode].libfunc
2937 = gen_rtx (SYMBOL_REF, Pmode, "__subdf3");
2938
2939#ifdef HAVE_mulqi3
2940 if (HAVE_mulqi3)
2941 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
2942#endif
2943#ifdef HAVE_mulhi3
2944 if (HAVE_mulhi3)
2945 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
2946#endif
2947#ifdef HAVE_mulpsi3
2948 if (HAVE_mulpsi3)
2949 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
2950#endif
2951#ifdef HAVE_mulsi3
2952 if (HAVE_mulsi3)
2953 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
2954#endif
2955#ifdef HAVE_muldi3
2956 if (HAVE_muldi3)
2957 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
2958#endif
2959#ifdef HAVE_multi3
2960 if (HAVE_multi3)
2961 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
2962#endif
2963#ifdef HAVE_mulsf3
2964 if (HAVE_mulsf3)
2965 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
2966#endif
2967#ifdef HAVE_muldf3
2968 if (HAVE_muldf3)
2969 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
2970#endif
2971#ifdef HAVE_multf3
2972 if (HAVE_multf3)
2973 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
2974#endif
2975
2976#ifdef MULSI3_LIBCALL
2977 smul_optab->handlers[(int) SImode].libfunc
2978 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
2979#else
2980 smul_optab->handlers[(int) SImode].libfunc
2981 = gen_rtx (SYMBOL_REF, Pmode, "__mulsi3");
2982#endif
2983#ifdef MULDI3_LIBCALL
2984 smul_optab->handlers[(int) DImode].libfunc
2985 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
2986#else
2987 smul_optab->handlers[(int) DImode].libfunc
2988 = gen_rtx (SYMBOL_REF, Pmode, "__muldi3");
2989#endif
2990 smul_optab->handlers[(int) SFmode].libfunc
2991 = gen_rtx (SYMBOL_REF, Pmode, "__mulsf3");
2992 smul_optab->handlers[(int) DFmode].libfunc
2993 = gen_rtx (SYMBOL_REF, Pmode, "__muldf3");
2994
2995#ifdef HAVE_mulqihi3
2996 if (HAVE_mulqihi3)
2997 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
2998#endif
2999#ifdef HAVE_mulhisi3
3000 if (HAVE_mulhisi3)
3001 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3002#endif
3003#ifdef HAVE_mulsidi3
3004 if (HAVE_mulsidi3)
3005 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3006#endif
3007#ifdef HAVE_mulditi3
3008 if (HAVE_mulditi3)
3009 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3010#endif
3011
3012#ifdef HAVE_umulqihi3
3013 if (HAVE_umulqihi3)
3014 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3015#endif
3016#ifdef HAVE_umulhisi3
3017 if (HAVE_umulhisi3)
3018 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3019#endif
3020#ifdef HAVE_umulsidi3
3021 if (HAVE_umulsidi3)
3022 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3023#endif
3024#ifdef HAVE_umulditi3
3025 if (HAVE_umulditi3)
3026 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3027#endif
3028
3029#ifdef HAVE_divqi3
3030 if (HAVE_divqi3)
3031 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3032#endif
3033#ifdef HAVE_divhi3
3034 if (HAVE_divhi3)
3035 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3036#endif
3037#ifdef HAVE_divpsi3
3038 if (HAVE_divpsi3)
3039 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3040#endif
3041#ifdef HAVE_divsi3
3042 if (HAVE_divsi3)
3043 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3044#endif
3045#ifdef HAVE_divdi3
3046 if (HAVE_divdi3)
3047 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3048#endif
3049#ifdef HAVE_divti3
3050 if (HAVE_divti3)
3051 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3052#endif
3053
3054#ifdef DIVSI3_LIBCALL
3055 sdiv_optab->handlers[(int) SImode].libfunc
3056 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3057#else
3058 sdiv_optab->handlers[(int) SImode].libfunc
3059 = gen_rtx (SYMBOL_REF, Pmode, "__divsi3");
3060#endif
3061#ifdef DIVDI3_LIBCALL
3062 sdiv_optab->handlers[(int) DImode].libfunc
3063 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3064#else
3065 sdiv_optab->handlers[(int) DImode].libfunc
3066 = gen_rtx (SYMBOL_REF, Pmode, "__divdi3");
3067#endif
3068
3069#ifdef HAVE_udivqi3
3070 if (HAVE_udivqi3)
3071 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3072#endif
3073#ifdef HAVE_udivhi3
3074 if (HAVE_udivhi3)
3075 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3076#endif
3077#ifdef HAVE_udivpsi3
3078 if (HAVE_udivpsi3)
3079 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3080#endif
3081#ifdef HAVE_udivsi3
3082 if (HAVE_udivsi3)
3083 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3084#endif
3085#ifdef HAVE_udivdi3
3086 if (HAVE_udivdi3)
3087 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3088#endif
3089#ifdef HAVE_udivti3
3090 if (HAVE_udivti3)
3091 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3092#endif
3093
3094#ifdef UDIVSI3_LIBCALL
3095 udiv_optab->handlers[(int) SImode].libfunc
3096 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3097#else
3098 udiv_optab->handlers[(int) SImode].libfunc
3099 = gen_rtx (SYMBOL_REF, Pmode, "__udivsi3");
3100#endif
3101#ifdef UDIVDI3_LIBCALL
3102 udiv_optab->handlers[(int) DImode].libfunc
3103 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3104#else
3105 udiv_optab->handlers[(int) DImode].libfunc
3106 = gen_rtx (SYMBOL_REF, Pmode, "__udivdi3");
3107#endif
3108
3109#ifdef HAVE_divmodqi4
3110 if (HAVE_divmodqi4)
3111 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3112#endif
3113#ifdef HAVE_divmodhi4
3114 if (HAVE_divmodhi4)
3115 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3116#endif
3117#ifdef HAVE_divmodsi4
3118 if (HAVE_divmodsi4)
3119 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3120#endif
3121#ifdef HAVE_divmoddi4
3122 if (HAVE_divmoddi4)
3123 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3124#endif
3125#ifdef HAVE_divmodti4
3126 if (HAVE_divmodti4)
3127 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3128#endif
3129
3130#ifdef HAVE_udivmodqi4
3131 if (HAVE_udivmodqi4)
3132 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3133#endif
3134#ifdef HAVE_udivmodhi4
3135 if (HAVE_udivmodhi4)
3136 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3137#endif
3138#ifdef HAVE_udivmodsi4
3139 if (HAVE_udivmodsi4)
3140 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3141#endif
3142#ifdef HAVE_udivmoddi4
3143 if (HAVE_udivmoddi4)
3144 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3145#endif
3146#ifdef HAVE_udivmodti4
3147 if (HAVE_udivmodti4)
3148 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3149#endif
3150
3151#ifdef HAVE_modqi3
3152 if (HAVE_modqi3)
3153 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3154#endif
3155#ifdef HAVE_modhi3
3156 if (HAVE_modhi3)
3157 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3158#endif
3159#ifdef HAVE_modpsi3
3160 if (HAVE_modpsi3)
3161 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3162#endif
3163#ifdef HAVE_modsi3
3164 if (HAVE_modsi3)
3165 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3166#endif
3167#ifdef HAVE_moddi3
3168 if (HAVE_moddi3)
3169 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3170#endif
3171#ifdef HAVE_modti3
3172 if (HAVE_modti3)
3173 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3174#endif
3175
3176#ifdef MODSI3_LIBCALL
3177 smod_optab->handlers[(int) SImode].libfunc
3178 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3179#else
3180 smod_optab->handlers[(int) SImode].libfunc
3181 = gen_rtx (SYMBOL_REF, Pmode, "__modsi3");
3182#endif
3183#ifdef MODDI3_LIBCALL
3184 smod_optab->handlers[(int) DImode].libfunc
3185 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3186#else
3187 smod_optab->handlers[(int) DImode].libfunc
3188 = gen_rtx (SYMBOL_REF, Pmode, "__moddi3");
3189#endif
3190
3191#ifdef HAVE_umodqi3
3192 if (HAVE_umodqi3)
3193 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3194#endif
3195#ifdef HAVE_umodhi3
3196 if (HAVE_umodhi3)
3197 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3198#endif
3199#ifdef HAVE_umodpsi3
3200 if (HAVE_umodpsi3)
3201 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3202#endif
3203#ifdef HAVE_umodsi3
3204 if (HAVE_umodsi3)
3205 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3206#endif
3207#ifdef HAVE_umoddi3
3208 if (HAVE_umoddi3)
3209 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3210#endif
3211#ifdef HAVE_umodti3
3212 if (HAVE_umodti3)
3213 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3214#endif
3215
3216#ifdef UMODSI3_LIBCALL
3217 umod_optab->handlers[(int) SImode].libfunc
3218 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3219#else
3220 umod_optab->handlers[(int) SImode].libfunc
3221 = gen_rtx (SYMBOL_REF, Pmode, "__umodsi3");
3222#endif
3223#ifdef UMODDI3_LIBCALL
3224 umod_optab->handlers[(int) DImode].libfunc
3225 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3226#else
3227 umod_optab->handlers[(int) DImode].libfunc
3228 = gen_rtx (SYMBOL_REF, Pmode, "__umoddi3");
3229#endif
3230
3231#ifdef HAVE_divsf3
3232 if (HAVE_divsf3)
3233 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3234#endif
3235#ifdef HAVE_divdf3
3236 if (HAVE_divdf3)
3237 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3238#endif
3239#ifdef HAVE_divtf3
3240 if (HAVE_divtf3)
3241 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3242#endif
3243 flodiv_optab->handlers[(int) SFmode].libfunc
3244 = gen_rtx (SYMBOL_REF, Pmode, "__divsf3");
3245 flodiv_optab->handlers[(int) DFmode].libfunc
3246 = gen_rtx (SYMBOL_REF, Pmode, "__divdf3");
3247
3248#ifdef HAVE_ftruncsf2
3249 if (HAVE_ftruncsf2)
3250 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3251#endif
3252#ifdef HAVE_ftruncdf2
3253 if (HAVE_ftruncdf2)
3254 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3255#endif
3256#ifdef HAVE_ftrunctf2
3257 if (HAVE_ftrunctf2)
3258 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3259#endif
3260
3261#ifdef HAVE_andqi3
3262 if (HAVE_andqi3)
3263 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3264#endif
3265#ifdef HAVE_andhi3
3266 if (HAVE_andhi3)
3267 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3268#endif
3269#ifdef HAVE_andpsi3
3270 if (HAVE_andpsi3)
3271 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3272#endif
3273#ifdef HAVE_andsi3
3274 if (HAVE_andsi3)
3275 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3276#endif
3277#ifdef HAVE_anddi3
3278 if (HAVE_anddi3)
3279 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3280#endif
3281#ifdef HAVE_andti3
3282 if (HAVE_andti3)
3283 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3284#endif
3285
3286#ifdef HAVE_iorqi3
3287 if (HAVE_iorqi3)
3288 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3289#endif
3290#ifdef HAVE_iorhi3
3291 if (HAVE_iorhi3)
3292 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3293#endif
3294#ifdef HAVE_iorpsi3
3295 if (HAVE_iorpsi3)
3296 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3297#endif
3298#ifdef HAVE_iorsi3
3299 if (HAVE_iorsi3)
3300 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3301#endif
3302#ifdef HAVE_iordi3
3303 if (HAVE_iordi3)
3304 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3305#endif
3306#ifdef HAVE_iorti3
3307 if (HAVE_iorti3)
3308 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3309#endif
3310
3311#ifdef HAVE_xorqi3
3312 if (HAVE_xorqi3)
3313 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3314#endif
3315#ifdef HAVE_xorhi3
3316 if (HAVE_xorhi3)
3317 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3318#endif
3319#ifdef HAVE_xorpsi3
3320 if (HAVE_xorpsi3)
3321 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3322#endif
3323#ifdef HAVE_xorsi3
3324 if (HAVE_xorsi3)
3325 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3326#endif
3327#ifdef HAVE_xordi3
3328 if (HAVE_xordi3)
3329 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3330#endif
3331#ifdef HAVE_xorti3
3332 if (HAVE_xorti3)
3333 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3334#endif
3335
3336#ifdef HAVE_ashlqi3
3337 if (HAVE_ashlqi3)
3338 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3339#endif
3340#ifdef HAVE_ashlhi3
3341 if (HAVE_ashlhi3)
3342 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3343#endif
3344#ifdef HAVE_ashlpsi3
3345 if (HAVE_ashlpsi3)
3346 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3347#endif
3348#ifdef HAVE_ashlsi3
3349 if (HAVE_ashlsi3)
3350 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3351#endif
3352#ifdef HAVE_ashldi3
3353 if (HAVE_ashldi3)
3354 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3355#endif
3356#ifdef HAVE_ashlti3
3357 if (HAVE_ashlti3)
3358 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3359#endif
3360 ashl_optab->handlers[(int) SImode].libfunc
3361 = gen_rtx (SYMBOL_REF, Pmode, "__ashlsi3");
3362 ashl_optab->handlers[(int) DImode].libfunc
3363 = gen_rtx (SYMBOL_REF, Pmode, "__ashldi3");
3364
3365#ifdef HAVE_ashrqi3
3366 if (HAVE_ashrqi3)
3367 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3368#endif
3369#ifdef HAVE_ashrhi3
3370 if (HAVE_ashrhi3)
3371 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3372#endif
3373#ifdef HAVE_ashrpsi3
3374 if (HAVE_ashrpsi3)
3375 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3376#endif
3377#ifdef HAVE_ashrsi3
3378 if (HAVE_ashrsi3)
3379 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3380#endif
3381#ifdef HAVE_ashrdi3
3382 if (HAVE_ashrdi3)
3383 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3384#endif
3385#ifdef HAVE_ashrti3
3386 if (HAVE_ashrti3)
3387 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3388#endif
3389 ashr_optab->handlers[(int) SImode].libfunc
3390 = gen_rtx (SYMBOL_REF, Pmode, "__ashrsi3");
3391 ashr_optab->handlers[(int) DImode].libfunc
3392 = gen_rtx (SYMBOL_REF, Pmode, "__ashrdi3");
3393
3394#ifdef HAVE_lshlqi3
3395 if (HAVE_lshlqi3)
3396 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3397#endif
3398#ifdef HAVE_lshlhi3
3399 if (HAVE_lshlhi3)
3400 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3401#endif
3402#ifdef HAVE_lshlpsi3
3403 if (HAVE_lshlpsi3)
3404 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3405#endif
3406#ifdef HAVE_lshlsi3
3407 if (HAVE_lshlsi3)
3408 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3409#endif
3410#ifdef HAVE_lshldi3
3411 if (HAVE_lshldi3)
3412 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3413#endif
3414#ifdef HAVE_lshlti3
3415 if (HAVE_lshlti3)
3416 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3417#endif
3418 lshl_optab->handlers[(int) SImode].libfunc
3419 = gen_rtx (SYMBOL_REF, Pmode, "__lshlsi3");
3420 lshl_optab->handlers[(int) DImode].libfunc
3421 = gen_rtx (SYMBOL_REF, Pmode, "__lshldi3");
3422
3423#ifdef HAVE_lshrqi3
3424 if (HAVE_lshrqi3)
3425 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3426#endif
3427#ifdef HAVE_lshrhi3
3428 if (HAVE_lshrhi3)
3429 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3430#endif
3431#ifdef HAVE_lshrpsi3
3432 if (HAVE_lshrpsi3)
3433 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3434#endif
3435#ifdef HAVE_lshrsi3
3436 if (HAVE_lshrsi3)
3437 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3438#endif
3439#ifdef HAVE_lshrdi3
3440 if (HAVE_lshrdi3)
3441 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3442#endif
3443#ifdef HAVE_lshrti3
3444 if (HAVE_lshrti3)
3445 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3446#endif
3447 lshr_optab->handlers[(int) SImode].libfunc
3448 = gen_rtx (SYMBOL_REF, Pmode, "__lshrsi3");
3449 lshr_optab->handlers[(int) DImode].libfunc
3450 = gen_rtx (SYMBOL_REF, Pmode, "__lshrdi3");
3451
3452#ifdef HAVE_rotlqi3
3453 if (HAVE_rotlqi3)
3454 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3455#endif
3456#ifdef HAVE_rotlhi3
3457 if (HAVE_rotlhi3)
3458 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3459#endif
3460#ifdef HAVE_rotlpsi3
3461 if (HAVE_rotlpsi3)
3462 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3463#endif
3464#ifdef HAVE_rotlsi3
3465 if (HAVE_rotlsi3)
3466 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3467#endif
3468#ifdef HAVE_rotldi3
3469 if (HAVE_rotldi3)
3470 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3471#endif
3472#ifdef HAVE_rotlti3
3473 if (HAVE_rotlti3)
3474 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3475#endif
3476 rotl_optab->handlers[(int) SImode].libfunc
3477 = gen_rtx (SYMBOL_REF, Pmode, "__rotlsi3");
3478 rotl_optab->handlers[(int) DImode].libfunc
3479 = gen_rtx (SYMBOL_REF, Pmode, "__rotldi3");
3480
3481#ifdef HAVE_rotrqi3
3482 if (HAVE_rotrqi3)
3483 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3484#endif
3485#ifdef HAVE_rotrhi3
3486 if (HAVE_rotrhi3)
3487 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3488#endif
3489#ifdef HAVE_rotrpsi3
3490 if (HAVE_rotrpsi3)
3491 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3492#endif
3493#ifdef HAVE_rotrsi3
3494 if (HAVE_rotrsi3)
3495 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3496#endif
3497#ifdef HAVE_rotrdi3
3498 if (HAVE_rotrdi3)
3499 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3500#endif
3501#ifdef HAVE_rotrti3
3502 if (HAVE_rotrti3)
3503 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3504#endif
3505 rotr_optab->handlers[(int) SImode].libfunc
3506 = gen_rtx (SYMBOL_REF, Pmode, "__rotrsi3");
3507 rotr_optab->handlers[(int) DImode].libfunc
3508 = gen_rtx (SYMBOL_REF, Pmode, "__rotrdi3");
3509
3510#ifdef HAVE_sminqi3
3511 if (HAVE_sminqi3)
3512 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3513#endif
3514#ifdef HAVE_sminhi3
3515 if (HAVE_sminhi3)
3516 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3517#endif
3518#ifdef HAVE_sminsi3
3519 if (HAVE_sminsi3)
3520 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3521#endif
3522#ifdef HAVE_smindi3
3523 if (HAVE_smindi3)
3524 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3525#endif
3526#ifdef HAVE_sminti3
3527 if (HAVE_sminti3)
3528 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3529#endif
3530#ifdef HAVE_sminsf3
3531 if (HAVE_sminsf3)
3532 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sminsf3;
3533#endif
3534#ifdef HAVE_smindf3
3535 if (HAVE_smindf3)
3536 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smindf3;
3537#endif
3538#ifdef HAVE_smintf3
3539 if (HAVE_smintf3)
3540 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smintf3;
3541#endif
3542
3543#ifdef HAVE_smaxqi3
3544 if (HAVE_smaxqi3)
3545 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
3546#endif
3547#ifdef HAVE_smaxhi3
3548 if (HAVE_smaxhi3)
3549 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
3550#endif
3551#ifdef HAVE_smaxsi3
3552 if (HAVE_smaxsi3)
3553 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
3554#endif
3555#ifdef HAVE_smaxdi3
3556 if (HAVE_smaxdi3)
3557 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
3558#endif
3559#ifdef HAVE_smaxti3
3560 if (HAVE_smaxti3)
3561 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
3562#endif
3563#ifdef HAVE_smaxsf3
3564 if (HAVE_smaxsf3)
3565 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_smaxsf3;
3566#endif
3567#ifdef HAVE_smaxdf3
3568 if (HAVE_smaxdf3)
3569 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smaxdf3;
3570#endif
3571#ifdef HAVE_smaxtf3
3572 if (HAVE_smaxtf3)
3573 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smaxtf3;
3574#endif
3575
3576#ifdef HAVE_uminqi3
3577 if (HAVE_uminqi3)
3578 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
3579#endif
3580#ifdef HAVE_uminhi3
3581 if (HAVE_uminhi3)
3582 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
3583#endif
3584#ifdef HAVE_uminsi3
3585 if (HAVE_uminsi3)
3586 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
3587#endif
3588#ifdef HAVE_umindi3
3589 if (HAVE_umindi3)
3590 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
3591#endif
3592#ifdef HAVE_uminti3
3593 if (HAVE_uminti3)
3594 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
3595#endif
3596
3597#ifdef HAVE_umaxqi3
3598 if (HAVE_umaxqi3)
3599 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
3600#endif
3601#ifdef HAVE_umaxhi3
3602 if (HAVE_umaxhi3)
3603 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
3604#endif
3605#ifdef HAVE_umaxsi3
3606 if (HAVE_umaxsi3)
3607 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
3608#endif
3609#ifdef HAVE_umaxdi3
3610 if (HAVE_umaxdi3)
3611 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
3612#endif
3613#ifdef HAVE_umaxti3
3614 if (HAVE_umaxti3)
3615 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
3616#endif
3617
3618#ifdef HAVE_negqi2
3619 if (HAVE_negqi2)
3620 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
3621#endif
3622#ifdef HAVE_neghi2
3623 if (HAVE_neghi2)
3624 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
3625#endif
3626#ifdef HAVE_negpsi2
3627 if (HAVE_negpsi2)
3628 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
3629#endif
3630#ifdef HAVE_negsi2
3631 if (HAVE_negsi2)
3632 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
3633#endif
3634#ifdef HAVE_negdi2
3635 if (HAVE_negdi2)
3636 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
3637#endif
3638#ifdef HAVE_negti2
3639 if (HAVE_negti2)
3640 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
3641#endif
3642#ifdef HAVE_negsf2
3643 if (HAVE_negsf2)
3644 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
3645#endif
3646#ifdef HAVE_negdf2
3647 if (HAVE_negdf2)
3648 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
3649#endif
3650#ifdef HAVE_negtf2
3651 if (HAVE_negtf2)
3652 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
3653#endif
3654 neg_optab->handlers[(int) SImode].libfunc
3655 = gen_rtx (SYMBOL_REF, Pmode, "__negsi2");
3656 neg_optab->handlers[(int) DImode].libfunc
3657 = gen_rtx (SYMBOL_REF, Pmode, "__negdi2");
3658 neg_optab->handlers[(int) SFmode].libfunc
3659 = gen_rtx (SYMBOL_REF, Pmode, "__negsf2");
3660 neg_optab->handlers[(int) DFmode].libfunc
3661 = gen_rtx (SYMBOL_REF, Pmode, "__negdf2");
3662
3663#ifdef HAVE_absqi2
3664 if (HAVE_absqi2)
3665 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
3666#endif
3667#ifdef HAVE_abshi2
3668 if (HAVE_abshi2)
3669 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
3670#endif
3671#ifdef HAVE_abspsi2
3672 if (HAVE_abspsi2)
3673 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
3674#endif
3675#ifdef HAVE_abssi2
3676 if (HAVE_abssi2)
3677 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
3678#endif
3679#ifdef HAVE_absdi2
3680 if (HAVE_absdi2)
3681 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
3682#endif
3683#ifdef HAVE_absti2
3684 if (HAVE_absti2)
3685 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
3686#endif
3687#ifdef HAVE_abssf2
3688 if (HAVE_abssf2)
3689 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
3690#endif
3691#ifdef HAVE_absdf2
3692 if (HAVE_absdf2)
3693 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
3694#endif
3695#ifdef HAVE_abstf2
3696 if (HAVE_abstf2)
3697 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
3698#endif
3699 /* No library calls here! If there is no abs instruction,
3700 expand_expr will generate a conditional negation. */
3701
d45cf215
RS
3702#ifdef HAVE_sqrtqi2
3703 if (HAVE_sqrtqi2)
3704 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
3705#endif
3706#ifdef HAVE_sqrthi2
3707 if (HAVE_sqrthi2)
3708 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
3709#endif
3710#ifdef HAVE_sqrtpsi2
3711 if (HAVE_sqrtpsi2)
3712 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
3713#endif
3714#ifdef HAVE_sqrtsi2
3715 if (HAVE_sqrtsi2)
3716 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
3717#endif
3718#ifdef HAVE_sqrtdi2
3719 if (HAVE_sqrtdi2)
3720 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
3721#endif
3722#ifdef HAVE_sqrtti2
3723 if (HAVE_sqrtti2)
3724 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
3725#endif
3726#ifdef HAVE_sqrtsf2
3727 if (HAVE_sqrtsf2)
3728 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
3729#endif
3730#ifdef HAVE_sqrtdf2
3731 if (HAVE_sqrtdf2)
3732 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
3733#endif
3734#ifdef HAVE_sqrttf2
3735 if (HAVE_sqrttf2)
3736 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
3737#endif
3738 /* No library calls here! If there is no sqrt instruction expand_builtin
3739 should force the library call. */
3740
19c3fc24
RS
3741#ifdef HAVE_strlenqi
3742 if (HAVE_strlenqi)
3743 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
3744#endif
3745#ifdef HAVE_strlenhi
3746 if (HAVE_strlenhi)
3747 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
3748#endif
3749#ifdef HAVE_strlenpsi
3750 if (HAVE_strlenpsi)
3751 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
3752#endif
3753#ifdef HAVE_strlensi
3754 if (HAVE_strlensi)
3755 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
3756#endif
3757#ifdef HAVE_strlendi
3758 if (HAVE_strlendi)
3759 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
3760#endif
3761#ifdef HAVE_strlenti
3762 if (HAVE_strlenti)
3763 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
3764#endif
3765 /* No library calls here! If there is no strlen instruction expand_builtin
3766 should force the library call. */
3767
77c9c6c2
RK
3768#ifdef HAVE_one_cmplqi2
3769 if (HAVE_one_cmplqi2)
3770 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
3771#endif
3772#ifdef HAVE_one_cmplhi2
3773 if (HAVE_one_cmplhi2)
3774 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
3775#endif
3776#ifdef HAVE_one_cmplpsi2
3777 if (HAVE_one_cmplpsi2)
3778 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
3779#endif
3780#ifdef HAVE_one_cmplsi2
3781 if (HAVE_one_cmplsi2)
3782 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
3783#endif
3784#ifdef HAVE_one_cmpldi2
3785 if (HAVE_one_cmpldi2)
3786 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
3787#endif
3788#ifdef HAVE_one_cmplti2
3789 if (HAVE_one_cmplti2)
3790 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
3791#endif
3792 one_cmpl_optab->handlers[(int) SImode].libfunc
3793 = gen_rtx (SYMBOL_REF, Pmode, "__one_cmplsi2");
3794
3795#ifdef HAVE_ffsqi2
3796 if (HAVE_ffsqi2)
3797 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
3798#endif
3799#ifdef HAVE_ffshi2
3800 if (HAVE_ffshi2)
3801 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
3802#endif
3803#ifdef HAVE_ffspsi2
3804 if (HAVE_ffspsi2)
3805 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
3806#endif
3807#ifdef HAVE_ffssi2
3808 if (HAVE_ffssi2)
3809 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
3810#endif
3811#ifdef HAVE_ffsdi2
3812 if (HAVE_ffsdi2)
3813 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
3814#endif
3815#ifdef HAVE_ffsti2
3816 if (HAVE_ffsti2)
3817 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
3818#endif
3819 ffs_optab->handlers[(int) SImode].libfunc
3820 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3821
3822#ifdef HAVE_movqi
3823 if (HAVE_movqi)
3824 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
3825#endif
3826#ifdef HAVE_movhi
3827 if (HAVE_movhi)
3828 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
3829#endif
3830#ifdef HAVE_movpsi
3831 if (HAVE_movpsi)
3832 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
3833#endif
3834#ifdef HAVE_movsi
3835 if (HAVE_movsi)
3836 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
3837#endif
3838#ifdef HAVE_movdi
3839 if (HAVE_movdi)
3840 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
3841#endif
3842#ifdef HAVE_movti
3843 if (HAVE_movti)
3844 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
3845#endif
3846#ifdef HAVE_movsf
3847 if (HAVE_movsf)
3848 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
3849#endif
3850#ifdef HAVE_movdf
3851 if (HAVE_movdf)
3852 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
3853#endif
3854#ifdef HAVE_movtf
3855 if (HAVE_movtf)
3856 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
3857#endif
3858#ifdef HAVE_movcc
3859 if (HAVE_movcc)
3860 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
3861#endif
3862
3863#ifdef EXTRA_CC_MODES
3864 init_mov_optab ();
3865#endif
3866
3867#ifdef HAVE_movstrictqi
3868 if (HAVE_movstrictqi)
3869 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
3870#endif
3871#ifdef HAVE_movstricthi
3872 if (HAVE_movstricthi)
3873 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
3874#endif
3875#ifdef HAVE_movstrictpsi
3876 if (HAVE_movstrictpsi)
3877 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
3878#endif
3879#ifdef HAVE_movstrictsi
3880 if (HAVE_movstrictsi)
3881 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
3882#endif
3883#ifdef HAVE_movstrictdi
3884 if (HAVE_movstrictdi)
3885 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
3886#endif
3887#ifdef HAVE_movstrictti
3888 if (HAVE_movstrictti)
3889 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
3890#endif
3891
3892#ifdef HAVE_cmpqi
3893 if (HAVE_cmpqi)
3894 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
3895#endif
3896#ifdef HAVE_cmphi
3897 if (HAVE_cmphi)
3898 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
3899#endif
3900#ifdef HAVE_cmppsi
3901 if (HAVE_cmppsi)
3902 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
3903#endif
3904#ifdef HAVE_cmpsi
3905 if (HAVE_cmpsi)
3906 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
3907#endif
3908#ifdef HAVE_cmpdi
3909 if (HAVE_cmpdi)
3910 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
3911#endif
3912#ifdef HAVE_cmpti
3913 if (HAVE_cmpti)
3914 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
3915#endif
3916#ifdef HAVE_cmpsf
3917 if (HAVE_cmpsf)
3918 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
3919#endif
3920#ifdef HAVE_cmpdf
3921 if (HAVE_cmpdf)
3922 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
3923#endif
3924#ifdef HAVE_cmptf
3925 if (HAVE_cmptf)
3926 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
3927#endif
3928#ifdef HAVE_tstqi
3929 if (HAVE_tstqi)
3930 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
3931#endif
3932#ifdef HAVE_tsthi
3933 if (HAVE_tsthi)
3934 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
3935#endif
3936#ifdef HAVE_tstpsi
3937 if (HAVE_tstpsi)
3938 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
3939#endif
3940#ifdef HAVE_tstsi
3941 if (HAVE_tstsi)
3942 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
3943#endif
3944#ifdef HAVE_tstdi
3945 if (HAVE_tstdi)
3946 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
3947#endif
3948#ifdef HAVE_tstti
3949 if (HAVE_tstti)
3950 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
3951#endif
3952#ifdef HAVE_tstsf
3953 if (HAVE_tstsf)
3954 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
3955#endif
3956#ifdef HAVE_tstdf
3957 if (HAVE_tstdf)
3958 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
3959#endif
3960#ifdef HAVE_tsttf
3961 if (HAVE_tsttf)
3962 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
3963#endif
3964 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3965 cmp_optab->handlers[(int) DImode].libfunc
3966 = gen_rtx (SYMBOL_REF, Pmode, "__cmpdi2");
3967 ucmp_optab->handlers[(int) DImode].libfunc
3968 = gen_rtx (SYMBOL_REF, Pmode, "__ucmpdi2");
3969
3970#ifdef HAVE_beq
3971 if (HAVE_beq)
3972 bcc_gen_fctn[(int) EQ] = gen_beq;
3973#endif
3974#ifdef HAVE_bne
3975 if (HAVE_bne)
3976 bcc_gen_fctn[(int) NE] = gen_bne;
3977#endif
3978#ifdef HAVE_bgt
3979 if (HAVE_bgt)
3980 bcc_gen_fctn[(int) GT] = gen_bgt;
3981#endif
3982#ifdef HAVE_bge
3983 if (HAVE_bge)
3984 bcc_gen_fctn[(int) GE] = gen_bge;
3985#endif
3986#ifdef HAVE_bgtu
3987 if (HAVE_bgtu)
3988 bcc_gen_fctn[(int) GTU] = gen_bgtu;
3989#endif
3990#ifdef HAVE_bgeu
3991 if (HAVE_bgeu)
3992 bcc_gen_fctn[(int) GEU] = gen_bgeu;
3993#endif
3994#ifdef HAVE_blt
3995 if (HAVE_blt)
3996 bcc_gen_fctn[(int) LT] = gen_blt;
3997#endif
3998#ifdef HAVE_ble
3999 if (HAVE_ble)
4000 bcc_gen_fctn[(int) LE] = gen_ble;
4001#endif
4002#ifdef HAVE_bltu
4003 if (HAVE_bltu)
4004 bcc_gen_fctn[(int) LTU] = gen_bltu;
4005#endif
4006#ifdef HAVE_bleu
4007 if (HAVE_bleu)
4008 bcc_gen_fctn[(int) LEU] = gen_bleu;
4009#endif
4010
4011 for (i = 0; i < NUM_RTX_CODE; i++)
4012 setcc_gen_code[i] = CODE_FOR_nothing;
4013
4014#ifdef HAVE_seq
4015 if (HAVE_seq)
4016 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4017#endif
4018#ifdef HAVE_sne
4019 if (HAVE_sne)
4020 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4021#endif
4022#ifdef HAVE_sgt
4023 if (HAVE_sgt)
4024 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4025#endif
4026#ifdef HAVE_sge
4027 if (HAVE_sge)
4028 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4029#endif
4030#ifdef HAVE_sgtu
4031 if (HAVE_sgtu)
4032 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4033#endif
4034#ifdef HAVE_sgeu
4035 if (HAVE_sgeu)
4036 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4037#endif
4038#ifdef HAVE_slt
4039 if (HAVE_slt)
4040 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4041#endif
4042#ifdef HAVE_sle
4043 if (HAVE_sle)
4044 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4045#endif
4046#ifdef HAVE_sltu
4047 if (HAVE_sltu)
4048 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4049#endif
4050#ifdef HAVE_sleu
4051 if (HAVE_sleu)
4052 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4053#endif
4054
4055 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4056 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4057 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4058 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4059 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4060 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4061 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4062 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4063 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4064 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4065 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4066 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4067 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4068 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4069 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4070 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4071 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4072 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4073 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4074 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
6bce1b78
RK
4075 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4076 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4077 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4078 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4079 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4080 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4081 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4082 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4083 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4084 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4085 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4086 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
77c9c6c2 4087}
7e1966ca
JVA
4088\f
4089#ifdef BROKEN_LDEXP
4090
4091/* SCO 3.2 apparently has a broken ldexp. */
4092
4093double
4094ldexp(x,n)
4095 double x;
4096 int n;
4097{
4098 if (n > 0)
4099 while (n--)
4100 x *= 2;
4101
4102 return x;
4103}
4104#endif /* BROKEN_LDEXP */
This page took 0.474339 seconds and 5 git commands to generate.