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