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