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