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