]> gcc.gnu.org Git - gcc.git/blob - gcc/optabs.c
(gen_move_insn): Big `if' applies only for MODE_CC class.
[gcc.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the 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 #include <ctype.h>
31
32 /* Each optab contains info on how this target machine
33 can perform a particular operation
34 for all sizes and kinds of operands.
35
36 The operation to be performed is often specified
37 by passing one of these optabs as an argument.
38
39 See expr.h for documentation of these optabs. */
40
41 optab add_optab;
42 optab sub_optab;
43 optab smul_optab;
44 optab smul_widen_optab;
45 optab umul_widen_optab;
46 optab sdiv_optab;
47 optab sdivmod_optab;
48 optab udiv_optab;
49 optab udivmod_optab;
50 optab smod_optab;
51 optab umod_optab;
52 optab flodiv_optab;
53 optab ftrunc_optab;
54 optab and_optab;
55 optab ior_optab;
56 optab xor_optab;
57 optab ashl_optab;
58 optab lshr_optab;
59 optab lshl_optab;
60 optab ashr_optab;
61 optab rotl_optab;
62 optab rotr_optab;
63 optab smin_optab;
64 optab smax_optab;
65 optab umin_optab;
66 optab umax_optab;
67
68 optab mov_optab;
69 optab movstrict_optab;
70
71 optab neg_optab;
72 optab abs_optab;
73 optab one_cmpl_optab;
74 optab ffs_optab;
75 optab sqrt_optab;
76 optab sin_optab;
77 optab cos_optab;
78
79 optab cmp_optab;
80 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
81 optab tst_optab;
82
83 optab strlen_optab;
84
85 /* SYMBOL_REF rtx's for the library functions that are called
86 implicitly and not via optabs. */
87
88 rtx extendsfdf2_libfunc;
89 rtx extendsfxf2_libfunc;
90 rtx extendsftf2_libfunc;
91 rtx extenddfxf2_libfunc;
92 rtx extenddftf2_libfunc;
93
94 rtx truncdfsf2_libfunc;
95 rtx truncxfsf2_libfunc;
96 rtx trunctfsf2_libfunc;
97 rtx truncxfdf2_libfunc;
98 rtx trunctfdf2_libfunc;
99
100 rtx memcpy_libfunc;
101 rtx bcopy_libfunc;
102 rtx memcmp_libfunc;
103 rtx bcmp_libfunc;
104 rtx memset_libfunc;
105 rtx bzero_libfunc;
106
107 rtx eqsf2_libfunc;
108 rtx nesf2_libfunc;
109 rtx gtsf2_libfunc;
110 rtx gesf2_libfunc;
111 rtx ltsf2_libfunc;
112 rtx lesf2_libfunc;
113
114 rtx eqdf2_libfunc;
115 rtx nedf2_libfunc;
116 rtx gtdf2_libfunc;
117 rtx gedf2_libfunc;
118 rtx ltdf2_libfunc;
119 rtx ledf2_libfunc;
120
121 rtx eqxf2_libfunc;
122 rtx nexf2_libfunc;
123 rtx gtxf2_libfunc;
124 rtx gexf2_libfunc;
125 rtx ltxf2_libfunc;
126 rtx lexf2_libfunc;
127
128 rtx eqtf2_libfunc;
129 rtx netf2_libfunc;
130 rtx gttf2_libfunc;
131 rtx getf2_libfunc;
132 rtx lttf2_libfunc;
133 rtx letf2_libfunc;
134
135 rtx floatsisf_libfunc;
136 rtx floatdisf_libfunc;
137 rtx floattisf_libfunc;
138
139 rtx floatsidf_libfunc;
140 rtx floatdidf_libfunc;
141 rtx floattidf_libfunc;
142
143 rtx floatsixf_libfunc;
144 rtx floatdixf_libfunc;
145 rtx floattixf_libfunc;
146
147 rtx floatsitf_libfunc;
148 rtx floatditf_libfunc;
149 rtx floattitf_libfunc;
150
151 rtx fixsfsi_libfunc;
152 rtx fixsfdi_libfunc;
153 rtx fixsfti_libfunc;
154
155 rtx fixdfsi_libfunc;
156 rtx fixdfdi_libfunc;
157 rtx fixdfti_libfunc;
158
159 rtx fixxfsi_libfunc;
160 rtx fixxfdi_libfunc;
161 rtx fixxfti_libfunc;
162
163 rtx fixtfsi_libfunc;
164 rtx fixtfdi_libfunc;
165 rtx fixtfti_libfunc;
166
167 rtx fixunssfsi_libfunc;
168 rtx fixunssfdi_libfunc;
169 rtx fixunssfti_libfunc;
170
171 rtx fixunsdfsi_libfunc;
172 rtx fixunsdfdi_libfunc;
173 rtx fixunsdfti_libfunc;
174
175 rtx fixunsxfsi_libfunc;
176 rtx fixunsxfdi_libfunc;
177 rtx fixunsxfti_libfunc;
178
179 rtx fixunstfsi_libfunc;
180 rtx fixunstfdi_libfunc;
181 rtx fixunstfti_libfunc;
182
183 /* from emit-rtl.c */
184 extern rtx gen_highpart ();
185
186 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
187 gives the gen_function to make a branch to test that condition. */
188
189 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
190
191 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
192 gives the insn code to make a store-condition insn
193 to test that condition. */
194
195 enum insn_code setcc_gen_code[NUM_RTX_CODE];
196
197 static void emit_float_lib_cmp ();
198 \f
199 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
200 the result of operation CODE applied to OP0 (and OP1 if it is a binary
201 operation).
202
203 If the last insn does not set TARGET, don't do anything, but return 1.
204
205 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
206 don't add the REG_EQUAL note but return 0. Our caller can then try
207 again, ensuring that TARGET is not one of the operands. */
208
209 static int
210 add_equal_note (seq, target, code, op0, op1)
211 rtx seq;
212 rtx target;
213 enum rtx_code code;
214 rtx op0, op1;
215 {
216 rtx set;
217 int i;
218 rtx note;
219
220 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
221 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
222 || GET_CODE (seq) != SEQUENCE
223 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
224 || GET_CODE (target) == ZERO_EXTRACT
225 || (! rtx_equal_p (SET_DEST (set), target)
226 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
227 SUBREG. */
228 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
229 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
230 target))))
231 return 1;
232
233 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
234 besides the last insn. */
235 if (reg_overlap_mentioned_p (target, op0)
236 || (op1 && reg_overlap_mentioned_p (target, op1)))
237 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
238 if (reg_set_p (target, XVECEXP (seq, 0, i)))
239 return 0;
240
241 if (GET_RTX_CLASS (code) == '1')
242 note = gen_rtx (code, GET_MODE (target), op0);
243 else
244 note = gen_rtx (code, GET_MODE (target), op0, op1);
245
246 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
247 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
248 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
249
250 return 1;
251 }
252 \f
253 /* Generate code to perform an operation specified by BINOPTAB
254 on operands OP0 and OP1, with result having machine-mode MODE.
255
256 UNSIGNEDP is for the case where we have to widen the operands
257 to perform the operation. It says to use zero-extension.
258
259 If TARGET is nonzero, the value
260 is generated there, if it is convenient to do so.
261 In all cases an rtx is returned for the locus of the value;
262 this may or may not be TARGET. */
263
264 rtx
265 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
266 enum machine_mode mode;
267 optab binoptab;
268 rtx op0, op1;
269 rtx target;
270 int unsignedp;
271 enum optab_methods methods;
272 {
273 enum mode_class class;
274 enum machine_mode wider_mode;
275 register rtx temp;
276 int commutative_op = 0;
277 int shift_op = (binoptab->code == ASHIFT
278 || binoptab->code == ASHIFTRT
279 || binoptab->code == LSHIFT
280 || binoptab->code == LSHIFTRT
281 || binoptab->code == ROTATE
282 || binoptab->code == ROTATERT);
283 rtx entry_last = get_last_insn ();
284 rtx last;
285
286 class = GET_MODE_CLASS (mode);
287
288 op0 = protect_from_queue (op0, 0);
289 op1 = protect_from_queue (op1, 0);
290 if (target)
291 target = protect_from_queue (target, 1);
292
293 if (flag_force_mem)
294 {
295 op0 = force_not_mem (op0);
296 op1 = force_not_mem (op1);
297 }
298
299 /* If subtracting an integer constant, convert this into an addition of
300 the negated constant. */
301
302 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
303 {
304 op1 = negate_rtx (mode, op1);
305 binoptab = add_optab;
306 }
307
308 /* If we are inside an appropriately-short loop and one operand is an
309 expensive constant, force it into a register. */
310 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
311 && rtx_cost (op0, binoptab->code) > 2)
312 op0 = force_reg (mode, op0);
313
314 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
315 && rtx_cost (op1, binoptab->code) > 2)
316 op1 = force_reg (shift_op ? word_mode : mode, op1);
317
318 /* Record where to delete back to if we backtrack. */
319 last = get_last_insn ();
320
321 /* If operation is commutative,
322 try to make the first operand a register.
323 Even better, try to make it the same as the target.
324 Also try to make the last operand a constant. */
325 if (GET_RTX_CLASS (binoptab->code) == 'c'
326 || binoptab == smul_widen_optab
327 || binoptab == umul_widen_optab)
328 {
329 commutative_op = 1;
330
331 if (((target == 0 || GET_CODE (target) == REG)
332 ? ((GET_CODE (op1) == REG
333 && GET_CODE (op0) != REG)
334 || target == op1)
335 : rtx_equal_p (op1, target))
336 || GET_CODE (op0) == CONST_INT)
337 {
338 temp = op1;
339 op1 = op0;
340 op0 = temp;
341 }
342 }
343
344 /* If we can do it with a three-operand insn, do so. */
345
346 if (methods != OPTAB_MUST_WIDEN
347 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
348 {
349 int icode = (int) binoptab->handlers[(int) mode].insn_code;
350 enum machine_mode mode0 = insn_operand_mode[icode][1];
351 enum machine_mode mode1 = insn_operand_mode[icode][2];
352 rtx pat;
353 rtx xop0 = op0, xop1 = op1;
354
355 if (target)
356 temp = target;
357 else
358 temp = gen_reg_rtx (mode);
359
360 /* If it is a commutative operator and the modes would match
361 if we would swap the operands, we can save the conversions. */
362 if (commutative_op)
363 {
364 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
365 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
366 {
367 register rtx tmp;
368
369 tmp = op0; op0 = op1; op1 = tmp;
370 tmp = xop0; xop0 = xop1; xop1 = tmp;
371 }
372 }
373
374 /* In case the insn wants input operands in modes different from
375 the result, convert the operands. */
376
377 if (GET_MODE (op0) != VOIDmode
378 && GET_MODE (op0) != mode0)
379 xop0 = convert_to_mode (mode0, xop0, unsignedp);
380
381 if (GET_MODE (xop1) != VOIDmode
382 && GET_MODE (xop1) != mode1)
383 xop1 = convert_to_mode (mode1, xop1, unsignedp);
384
385 /* Now, if insn's predicates don't allow our operands, put them into
386 pseudo regs. */
387
388 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
389 xop0 = copy_to_mode_reg (mode0, xop0);
390
391 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
392 xop1 = copy_to_mode_reg (mode1, xop1);
393
394 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
395 temp = gen_reg_rtx (mode);
396
397 pat = GEN_FCN (icode) (temp, xop0, xop1);
398 if (pat)
399 {
400 /* If PAT is a multi-insn sequence, try to add an appropriate
401 REG_EQUAL note to it. If we can't because TEMP conflicts with an
402 operand, call ourselves again, this time without a target. */
403 if (GET_CODE (pat) == SEQUENCE
404 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
405 {
406 delete_insns_since (last);
407 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
408 unsignedp, methods);
409 }
410
411 emit_insn (pat);
412 return temp;
413 }
414 else
415 delete_insns_since (last);
416 }
417
418 /* If this is a multiply, see if we can do a widening operation that
419 takes operands of this mode and makes a wider mode. */
420
421 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
422 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
423 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
424 != CODE_FOR_nothing))
425 {
426 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
427 unsignedp ? umul_widen_optab : smul_widen_optab,
428 op0, op1, 0, unsignedp, OPTAB_DIRECT);
429
430 if (GET_MODE_CLASS (mode) == MODE_INT)
431 return gen_lowpart (mode, temp);
432 else
433 return convert_to_mode (mode, temp, unsignedp);
434 }
435
436 /* Look for a wider mode of the same class for which we think we
437 can open-code the operation. Check for a widening multiply at the
438 wider mode as well. */
439
440 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
441 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
442 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
443 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
444 {
445 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
446 || (binoptab == smul_optab
447 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
448 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
449 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
450 != CODE_FOR_nothing)))
451 {
452 rtx xop0 = op0, xop1 = op1;
453 int no_extend = 0;
454
455 /* For certain integer operations, we need not actually extend
456 the narrow operands, as long as we will truncate
457 the results to the same narrowness. Don't do this when
458 WIDER_MODE is wider than a word since a paradoxical SUBREG
459 isn't valid for such modes. */
460
461 if ((binoptab == ior_optab || binoptab == and_optab
462 || binoptab == xor_optab
463 || binoptab == add_optab || binoptab == sub_optab
464 || binoptab == smul_optab
465 || binoptab == ashl_optab || binoptab == lshl_optab)
466 && class == MODE_INT
467 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
468 no_extend = 1;
469
470 /* If an operand is a constant integer, we might as well
471 convert it since that is more efficient than using a SUBREG,
472 unlike the case for other operands. Similarly for
473 SUBREGs that were made due to promoted objects. */
474
475 if (no_extend && GET_MODE (xop0) != VOIDmode
476 && ! (GET_CODE (xop0) == SUBREG
477 && SUBREG_PROMOTED_VAR_P (xop0)))
478 xop0 = gen_rtx (SUBREG, wider_mode,
479 force_reg (GET_MODE (xop0), xop0), 0);
480 else
481 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
482
483 if (no_extend && GET_MODE (xop1) != VOIDmode
484 && ! (GET_CODE (xop1) == SUBREG
485 && SUBREG_PROMOTED_VAR_P (xop1)))
486 xop1 = gen_rtx (SUBREG, wider_mode,
487 force_reg (GET_MODE (xop1), xop1), 0);
488 else
489 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
490
491 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
492 unsignedp, OPTAB_DIRECT);
493 if (temp)
494 {
495 if (class != MODE_INT)
496 {
497 if (target == 0)
498 target = gen_reg_rtx (mode);
499 convert_move (target, temp, 0);
500 return target;
501 }
502 else
503 return gen_lowpart (mode, temp);
504 }
505 else
506 delete_insns_since (last);
507 }
508 }
509
510 /* These can be done a word at a time. */
511 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
512 && class == MODE_INT
513 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
514 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
515 {
516 int i;
517 rtx insns;
518 rtx equiv_value;
519
520 /* If TARGET is the same as one of the operands, the REG_EQUAL note
521 won't be accurate, so use a new target. */
522 if (target == 0 || target == op0 || target == op1)
523 target = gen_reg_rtx (mode);
524
525 start_sequence ();
526
527 /* Do the actual arithmetic. */
528 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
529 {
530 rtx target_piece = operand_subword (target, i, 1, mode);
531 rtx x = expand_binop (word_mode, binoptab,
532 operand_subword_force (op0, i, mode),
533 operand_subword_force (op1, i, mode),
534 target_piece, unsignedp, methods);
535 if (target_piece != x)
536 emit_move_insn (target_piece, x);
537 }
538
539 insns = get_insns ();
540 end_sequence ();
541
542 if (binoptab->code != UNKNOWN)
543 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
544 else
545 equiv_value = 0;
546
547 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
548 return target;
549 }
550
551 /* These can be done a word at a time by propagating carries. */
552 if ((binoptab == add_optab || binoptab == sub_optab)
553 && class == MODE_INT
554 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
555 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
556 {
557 int i;
558 rtx carry_tmp = gen_reg_rtx (word_mode);
559 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
560 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
561 rtx carry_in, carry_out;
562 rtx xop0, xop1;
563
564 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
565 value is one of those, use it. Otherwise, use 1 since it is the
566 one easiest to get. */
567 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
568 int normalizep = STORE_FLAG_VALUE;
569 #else
570 int normalizep = 1;
571 #endif
572
573 /* Prepare the operands. */
574 xop0 = force_reg (mode, op0);
575 xop1 = force_reg (mode, op1);
576
577 if (target == 0 || GET_CODE (target) != REG
578 || target == xop0 || target == xop1)
579 target = gen_reg_rtx (mode);
580
581 /* Do the actual arithmetic. */
582 for (i = 0; i < nwords; i++)
583 {
584 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
585 rtx target_piece = operand_subword (target, index, 1, mode);
586 rtx op0_piece = operand_subword_force (xop0, index, mode);
587 rtx op1_piece = operand_subword_force (xop1, index, mode);
588 rtx x;
589
590 /* Main add/subtract of the input operands. */
591 x = expand_binop (word_mode, binoptab,
592 op0_piece, op1_piece,
593 target_piece, unsignedp, methods);
594 if (x == 0)
595 break;
596
597 if (i + 1 < nwords)
598 {
599 /* Store carry from main add/subtract. */
600 carry_out = gen_reg_rtx (word_mode);
601 carry_out = emit_store_flag (carry_out,
602 binoptab == add_optab ? LTU : GTU,
603 x, op0_piece,
604 word_mode, 1, normalizep);
605 if (!carry_out)
606 break;
607 }
608
609 if (i > 0)
610 {
611 /* Add/subtract previous carry to main result. */
612 x = expand_binop (word_mode,
613 normalizep == 1 ? binoptab : otheroptab,
614 x, carry_in,
615 target_piece, 1, methods);
616 if (target_piece != x)
617 emit_move_insn (target_piece, x);
618
619 if (i + 1 < nwords)
620 {
621 /* THIS CODE HAS NOT BEEN TESTED. */
622 /* Get out carry from adding/subtracting carry in. */
623 carry_tmp = emit_store_flag (carry_tmp,
624 binoptab == add_optab
625 ? LTU : GTU,
626 x, carry_in,
627 word_mode, 1, normalizep);
628 /* Logical-ior the two poss. carry together. */
629 carry_out = expand_binop (word_mode, ior_optab,
630 carry_out, carry_tmp,
631 carry_out, 0, methods);
632 if (!carry_out)
633 break;
634 }
635 }
636
637 carry_in = carry_out;
638 }
639
640 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
641 {
642 rtx temp;
643
644 temp = emit_move_insn (target, target);
645 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
646 gen_rtx (binoptab->code, mode, xop0, xop1),
647 REG_NOTES (temp));
648 return target;
649 }
650 else
651 delete_insns_since (last);
652 }
653
654 /* If we want to multiply two two-word values and have normal and widening
655 multiplies of single-word values, we can do this with three smaller
656 multiplications. Note that we do not make a REG_NO_CONFLICT block here
657 because we are not operating on one word at a time.
658
659 The multiplication proceeds as follows:
660 _______________________
661 [__op0_high_|__op0_low__]
662 _______________________
663 * [__op1_high_|__op1_low__]
664 _______________________________________________
665 _______________________
666 (1) [__op0_low__*__op1_low__]
667 _______________________
668 (2a) [__op0_low__*__op1_high_]
669 _______________________
670 (2b) [__op0_high_*__op1_low__]
671 _______________________
672 (3) [__op0_high_*__op1_high_]
673
674
675 This gives a 4-word result. Since we are only interested in the
676 lower 2 words, partial result (3) and the upper words of (2a) and
677 (2b) don't need to be calculated. Hence (2a) and (2b) can be
678 calculated using non-widening multiplication.
679
680 (1), however, needs to be calculated with an unsigned widening
681 multiplication. If this operation is not directly supported we
682 try using a signed widening multiplication and adjust the result.
683 This adjustment works as follows:
684
685 If both operands are positive then no adjustment is needed.
686
687 If the operands have different signs, for example op0_low < 0 and
688 op1_low >= 0, the instruction treats the most significant bit of
689 op0_low as a sign bit instead of a bit with significance
690 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
691 with 2**BITS_PER_WORD - op0_low, and two's complements the
692 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
693 the result.
694
695 Similarly, if both operands are negative, we need to add
696 (op0_low + op1_low) * 2**BITS_PER_WORD.
697
698 We use a trick to adjust quickly. We logically shift op0_low right
699 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
700 op0_high (op1_high) before it is used to calculate 2b (2a). If no
701 logical shift exists, we do an arithmetic right shift and subtract
702 the 0 or -1. */
703
704 if (binoptab == smul_optab
705 && class == MODE_INT
706 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
707 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
708 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
709 && ((umul_widen_optab->handlers[(int) mode].insn_code
710 != CODE_FOR_nothing)
711 || (smul_widen_optab->handlers[(int) mode].insn_code
712 != CODE_FOR_nothing)))
713 {
714 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
715 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
716 rtx op0_high = operand_subword_force (op0, high, mode);
717 rtx op0_low = operand_subword_force (op0, low, mode);
718 rtx op1_high = operand_subword_force (op1, high, mode);
719 rtx op1_low = operand_subword_force (op1, low, mode);
720 rtx product = 0;
721 rtx op0_xhigh;
722 rtx op1_xhigh;
723
724 /* If the target is the same as one of the inputs, don't use it. This
725 prevents problems with the REG_EQUAL note. */
726 if (target == op0 || target == op1)
727 target = 0;
728
729 /* Multiply the two lower words to get a double-word product.
730 If unsigned widening multiplication is available, use that;
731 otherwise use the signed form and compensate. */
732
733 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
734 {
735 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
736 target, 1, OPTAB_DIRECT);
737
738 /* If we didn't succeed, delete everything we did so far. */
739 if (product == 0)
740 delete_insns_since (last);
741 else
742 op0_xhigh = op0_high, op1_xhigh = op1_high;
743 }
744
745 if (product == 0
746 && smul_widen_optab->handlers[(int) mode].insn_code
747 != CODE_FOR_nothing)
748 {
749 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
750 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
751 target, 1, OPTAB_DIRECT);
752 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
753 NULL_RTX, 1, OPTAB_DIRECT);
754 if (op0_xhigh)
755 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
756 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
757 else
758 {
759 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
760 NULL_RTX, 0, OPTAB_DIRECT);
761 if (op0_xhigh)
762 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
763 op0_xhigh, op0_xhigh, 0,
764 OPTAB_DIRECT);
765 }
766
767 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
768 NULL_RTX, 1, OPTAB_DIRECT);
769 if (op1_xhigh)
770 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
771 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
772 else
773 {
774 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
775 NULL_RTX, 0, OPTAB_DIRECT);
776 if (op1_xhigh)
777 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
778 op1_xhigh, op1_xhigh, 0,
779 OPTAB_DIRECT);
780 }
781 }
782
783 /* If we have been able to directly compute the product of the
784 low-order words of the operands and perform any required adjustments
785 of the operands, we proceed by trying two more multiplications
786 and then computing the appropriate sum.
787
788 We have checked above that the required addition is provided.
789 Full-word addition will normally always succeed, especially if
790 it is provided at all, so we don't worry about its failure. The
791 multiplication may well fail, however, so we do handle that. */
792
793 if (product && op0_xhigh && op1_xhigh)
794 {
795 rtx product_piece;
796 rtx product_high = operand_subword (product, high, 1, mode);
797 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
798 NULL_RTX, 0, OPTAB_DIRECT);
799
800 if (temp)
801 {
802 product_piece = expand_binop (word_mode, add_optab, temp,
803 product_high, product_high,
804 0, OPTAB_LIB_WIDEN);
805 if (product_piece != product_high)
806 emit_move_insn (product_high, product_piece);
807
808 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
809 NULL_RTX, 0, OPTAB_DIRECT);
810
811 product_piece = expand_binop (word_mode, add_optab, temp,
812 product_high, product_high,
813 0, OPTAB_LIB_WIDEN);
814 if (product_piece != product_high)
815 emit_move_insn (product_high, product_piece);
816
817 temp = emit_move_insn (product, product);
818 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
819 gen_rtx (MULT, mode, op0, op1),
820 REG_NOTES (temp));
821
822 return product;
823 }
824 }
825
826 /* If we get here, we couldn't do it for some reason even though we
827 originally thought we could. Delete anything we've emitted in
828 trying to do it. */
829
830 delete_insns_since (last);
831 }
832
833 /* We need to open-code the complex type operations: '+, -, * and /' */
834
835 /* At this point we allow operations between two similar complex
836 numbers, and also if one of the operands is not a complex number
837 but rather of MODE_FLOAT or MODE_INT. However, the caller
838 must make sure that the MODE of the non-complex operand matches
839 the SUBMODE of the complex operand. */
840
841 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
842 {
843 rtx real0 = (rtx) 0;
844 rtx imag0 = (rtx) 0;
845 rtx real1 = (rtx) 0;
846 rtx imag1 = (rtx) 0;
847 rtx realr;
848 rtx imagr;
849 rtx res;
850 rtx seq;
851 rtx equiv_value;
852
853 /* Find the correct mode for the real and imaginary parts */
854 enum machine_mode submode
855 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
856 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
857 0);
858
859 if (submode == BLKmode)
860 abort ();
861
862 if (! target)
863 target = gen_reg_rtx (mode);
864
865 start_sequence ();
866
867 realr = gen_realpart (submode, target);
868 imagr = gen_imagpart (submode, target);
869
870 if (GET_MODE (op0) == mode)
871 {
872 real0 = gen_realpart (submode, op0);
873 imag0 = gen_imagpart (submode, op0);
874 }
875 else
876 real0 = op0;
877
878 if (GET_MODE (op1) == mode)
879 {
880 real1 = gen_realpart (submode, op1);
881 imag1 = gen_imagpart (submode, op1);
882 }
883 else
884 real1 = op1;
885
886 if (! real0 || ! real1 || ! (imag0 || imag1))
887 abort ();
888
889 switch (binoptab->code)
890 {
891 case PLUS:
892 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
893 case MINUS:
894 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
895 res = expand_binop (submode, binoptab, real0, real1,
896 realr, unsignedp, methods);
897 if (res != realr)
898 emit_move_insn (realr, res);
899
900 if (imag0 && imag1)
901 res = expand_binop (submode, binoptab, imag0, imag1,
902 imagr, unsignedp, methods);
903 else if (imag0)
904 res = imag0;
905 else if (binoptab->code == MINUS)
906 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
907 else
908 res = imag1;
909
910 if (res != imagr)
911 emit_move_insn (imagr, res);
912 break;
913
914 case MULT:
915 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
916
917 if (imag0 && imag1)
918 {
919 rtx temp =
920 expand_binop (submode, sub_optab,
921 expand_binop (submode, binoptab, real0,
922 real1, 0, unsignedp, methods),
923 expand_binop (submode, binoptab, imag0,
924 imag1, 0, unsignedp, methods),
925 realr, unsignedp, methods);
926
927 if (temp != realr)
928 emit_move_insn (realr, temp);
929
930 res = expand_binop (submode, add_optab,
931 expand_binop (submode, binoptab,
932 real0, imag1,
933 0, unsignedp, methods),
934 expand_binop (submode, binoptab,
935 real1, imag0,
936 0, unsignedp, methods),
937 imagr, unsignedp, methods);
938 if (res != imagr)
939 emit_move_insn (imagr, res);
940 }
941 else
942 {
943 res = expand_binop (submode, binoptab, real0, real1,
944 realr, unsignedp, methods);
945 if (res != realr)
946 emit_move_insn (realr, res);
947
948 if (imag0)
949 res = expand_binop (submode, binoptab,
950 real1, imag0, imagr, unsignedp, methods);
951 else
952 res = expand_binop (submode, binoptab,
953 real0, imag1, imagr, unsignedp, methods);
954 if (res != imagr)
955 emit_move_insn (imagr, res);
956 }
957 break;
958
959 case DIV:
960 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
961
962 if (! imag1)
963 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
964 /* Simply divide the real and imaginary parts by `c' */
965 res = expand_binop (submode, binoptab, real0, real1,
966 realr, unsignedp, methods);
967 if (res != realr)
968 emit_move_insn (realr, res);
969
970 res = expand_binop (submode, binoptab, imag0, real1,
971 imagr, unsignedp, methods);
972 if (res != imagr)
973 emit_move_insn (imagr, res);
974 }
975 else /* Divisor is of complex type */
976 { /* X/(a+ib) */
977
978 rtx divisor;
979 rtx real_t;
980 rtx imag_t;
981
982 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
983
984 /* Divisor: c*c + d*d */
985 divisor = expand_binop (submode, add_optab,
986 expand_binop (submode, mulopt,
987 real1, real1,
988 0, unsignedp, methods),
989 expand_binop (submode, mulopt,
990 imag1, imag1,
991 0, unsignedp, methods),
992 0, unsignedp, methods);
993
994 if (! imag0) /* ((a)(c-id))/divisor */
995 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
996 /* Calculate the dividend */
997 real_t = expand_binop (submode, mulopt, real0, real1,
998 0, unsignedp, methods);
999
1000 imag_t
1001 = expand_unop (submode, neg_optab,
1002 expand_binop (submode, mulopt, real0, imag1,
1003 0, unsignedp, methods),
1004 0, unsignedp);
1005 }
1006 else /* ((a+ib)(c-id))/divider */
1007 {
1008 /* Calculate the dividend */
1009 real_t = expand_binop (submode, add_optab,
1010 expand_binop (submode, mulopt,
1011 real0, real1,
1012 0, unsignedp, methods),
1013 expand_binop (submode, mulopt,
1014 imag0, imag1,
1015 0, unsignedp, methods),
1016 0, unsignedp, methods);
1017
1018 imag_t = expand_binop (submode, sub_optab,
1019 expand_binop (submode, mulopt,
1020 imag0, real1,
1021 0, unsignedp, methods),
1022 expand_binop (submode, mulopt,
1023 real0, imag1,
1024 0, unsignedp, methods),
1025 0, unsignedp, methods);
1026
1027 }
1028
1029 res = expand_binop (submode, binoptab, real_t, divisor,
1030 realr, unsignedp, methods);
1031 if (res != realr)
1032 emit_move_insn (realr, res);
1033
1034 res = expand_binop (submode, binoptab, imag_t, divisor,
1035 imagr, unsignedp, methods);
1036 if (res != imagr)
1037 emit_move_insn (imagr, res);
1038 }
1039 break;
1040
1041 default:
1042 abort ();
1043 }
1044
1045 seq = get_insns ();
1046 end_sequence ();
1047
1048 if (binoptab->code != UNKNOWN)
1049 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
1050 else
1051 equiv_value = 0;
1052
1053 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1054
1055 return target;
1056 }
1057
1058 /* It can't be open-coded in this mode.
1059 Use a library call if one is available and caller says that's ok. */
1060
1061 if (binoptab->handlers[(int) mode].libfunc
1062 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1063 {
1064 rtx insns;
1065 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1066 rtx op1x = op1;
1067 enum machine_mode op1_mode = mode;
1068
1069 start_sequence ();
1070
1071 if (shift_op)
1072 {
1073 op1_mode = word_mode;
1074 /* Specify unsigned here,
1075 since negative shift counts are meaningless. */
1076 op1x = convert_to_mode (word_mode, op1, 1);
1077 }
1078
1079 /* Pass 1 for NO_QUEUE so we don't lose any increments
1080 if the libcall is cse'd or moved. */
1081 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1082 1, mode, 2, op0, mode, op1x, op1_mode);
1083
1084 insns = get_insns ();
1085 end_sequence ();
1086
1087 target = gen_reg_rtx (mode);
1088 emit_libcall_block (insns, target, hard_libcall_value (mode),
1089 gen_rtx (binoptab->code, mode, op0, op1));
1090
1091 return target;
1092 }
1093
1094 delete_insns_since (last);
1095
1096 /* It can't be done in this mode. Can we do it in a wider mode? */
1097
1098 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1099 || methods == OPTAB_MUST_WIDEN))
1100 {
1101 /* Caller says, don't even try. */
1102 delete_insns_since (entry_last);
1103 return 0;
1104 }
1105
1106 /* Compute the value of METHODS to pass to recursive calls.
1107 Don't allow widening to be tried recursively. */
1108
1109 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1110
1111 /* Look for a wider mode of the same class for which it appears we can do
1112 the operation. */
1113
1114 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1115 {
1116 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1117 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1118 {
1119 if ((binoptab->handlers[(int) wider_mode].insn_code
1120 != CODE_FOR_nothing)
1121 || (methods == OPTAB_LIB
1122 && binoptab->handlers[(int) wider_mode].libfunc))
1123 {
1124 rtx xop0 = op0, xop1 = op1;
1125 int no_extend = 0;
1126
1127 /* For certain integer operations, we need not actually extend
1128 the narrow operands, as long as we will truncate
1129 the results to the same narrowness. Don't do this when
1130 WIDER_MODE is wider than a word since a paradoxical SUBREG
1131 isn't valid for such modes. */
1132
1133 if ((binoptab == ior_optab || binoptab == and_optab
1134 || binoptab == xor_optab
1135 || binoptab == add_optab || binoptab == sub_optab
1136 || binoptab == smul_optab
1137 || binoptab == ashl_optab || binoptab == lshl_optab)
1138 && class == MODE_INT
1139 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1140 no_extend = 1;
1141
1142 /* If an operand is a constant integer, we might as well
1143 convert it since that is more efficient than using a SUBREG,
1144 unlike the case for other operands. Similarly for
1145 SUBREGs that were made due to promoted objects.*/
1146
1147 if (no_extend && GET_MODE (xop0) != VOIDmode
1148 && ! (GET_CODE (xop0) == SUBREG
1149 && SUBREG_PROMOTED_VAR_P (xop0)))
1150 xop0 = gen_rtx (SUBREG, wider_mode,
1151 force_reg (GET_MODE (xop0), xop0), 0);
1152 else
1153 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1154
1155 if (no_extend && GET_MODE (xop1) != VOIDmode
1156 && ! (GET_CODE (xop1) == SUBREG
1157 && SUBREG_PROMOTED_VAR_P (xop1)))
1158 xop1 = gen_rtx (SUBREG, wider_mode,
1159 force_reg (GET_MODE (xop1), xop1), 0);
1160 else
1161 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1162
1163 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1164 unsignedp, methods);
1165 if (temp)
1166 {
1167 if (class != MODE_INT)
1168 {
1169 if (target == 0)
1170 target = gen_reg_rtx (mode);
1171 convert_move (target, temp, 0);
1172 return target;
1173 }
1174 else
1175 return gen_lowpart (mode, temp);
1176 }
1177 else
1178 delete_insns_since (last);
1179 }
1180 }
1181 }
1182
1183 delete_insns_since (entry_last);
1184 return 0;
1185 }
1186 \f
1187 /* Expand a binary operator which has both signed and unsigned forms.
1188 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1189 signed operations.
1190
1191 If we widen unsigned operands, we may use a signed wider operation instead
1192 of an unsigned wider operation, since the result would be the same. */
1193
1194 rtx
1195 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1196 enum machine_mode mode;
1197 optab uoptab, soptab;
1198 rtx op0, op1, target;
1199 int unsignedp;
1200 enum optab_methods methods;
1201 {
1202 register rtx temp;
1203 optab direct_optab = unsignedp ? uoptab : soptab;
1204 struct optab wide_soptab;
1205
1206 /* Do it without widening, if possible. */
1207 temp = expand_binop (mode, direct_optab, op0, op1, target,
1208 unsignedp, OPTAB_DIRECT);
1209 if (temp || methods == OPTAB_DIRECT)
1210 return temp;
1211
1212 /* Try widening to a signed int. Make a fake signed optab that
1213 hides any signed insn for direct use. */
1214 wide_soptab = *soptab;
1215 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1216 wide_soptab.handlers[(int) mode].libfunc = 0;
1217
1218 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1219 unsignedp, OPTAB_WIDEN);
1220
1221 /* For unsigned operands, try widening to an unsigned int. */
1222 if (temp == 0 && unsignedp)
1223 temp = expand_binop (mode, uoptab, op0, op1, target,
1224 unsignedp, OPTAB_WIDEN);
1225 if (temp || methods == OPTAB_WIDEN)
1226 return temp;
1227
1228 /* Use the right width lib call if that exists. */
1229 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1230 if (temp || methods == OPTAB_LIB)
1231 return temp;
1232
1233 /* Must widen and use a lib call, use either signed or unsigned. */
1234 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1235 unsignedp, methods);
1236 if (temp != 0)
1237 return temp;
1238 if (unsignedp)
1239 return expand_binop (mode, uoptab, op0, op1, target,
1240 unsignedp, methods);
1241 return 0;
1242 }
1243 \f
1244 /* Generate code to perform an operation specified by BINOPTAB
1245 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1246 We assume that the order of the operands for the instruction
1247 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1248 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1249
1250 Either TARG0 or TARG1 may be zero, but what that means is that
1251 that result is not actually wanted. We will generate it into
1252 a dummy pseudo-reg and discard it. They may not both be zero.
1253
1254 Returns 1 if this operation can be performed; 0 if not. */
1255
1256 int
1257 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1258 optab binoptab;
1259 rtx op0, op1;
1260 rtx targ0, targ1;
1261 int unsignedp;
1262 {
1263 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1264 enum mode_class class;
1265 enum machine_mode wider_mode;
1266 rtx entry_last = get_last_insn ();
1267 rtx last;
1268
1269 class = GET_MODE_CLASS (mode);
1270
1271 op0 = protect_from_queue (op0, 0);
1272 op1 = protect_from_queue (op1, 0);
1273
1274 if (flag_force_mem)
1275 {
1276 op0 = force_not_mem (op0);
1277 op1 = force_not_mem (op1);
1278 }
1279
1280 /* If we are inside an appropriately-short loop and one operand is an
1281 expensive constant, force it into a register. */
1282 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1283 && rtx_cost (op0, binoptab->code) > 2)
1284 op0 = force_reg (mode, op0);
1285
1286 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1287 && rtx_cost (op1, binoptab->code) > 2)
1288 op1 = force_reg (mode, op1);
1289
1290 if (targ0)
1291 targ0 = protect_from_queue (targ0, 1);
1292 else
1293 targ0 = gen_reg_rtx (mode);
1294 if (targ1)
1295 targ1 = protect_from_queue (targ1, 1);
1296 else
1297 targ1 = gen_reg_rtx (mode);
1298
1299 /* Record where to go back to if we fail. */
1300 last = get_last_insn ();
1301
1302 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1303 {
1304 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1305 enum machine_mode mode0 = insn_operand_mode[icode][1];
1306 enum machine_mode mode1 = insn_operand_mode[icode][2];
1307 rtx pat;
1308 rtx xop0 = op0, xop1 = op1;
1309
1310 /* In case this insn wants input operands in modes different from the
1311 result, convert the operands. */
1312 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1313 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1314
1315 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1316 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1317
1318 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1319 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1320 xop0 = copy_to_mode_reg (mode0, xop0);
1321
1322 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1323 xop1 = copy_to_mode_reg (mode1, xop1);
1324
1325 /* We could handle this, but we should always be called with a pseudo
1326 for our targets and all insns should take them as outputs. */
1327 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1328 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1329 abort ();
1330
1331 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1332 if (pat)
1333 {
1334 emit_insn (pat);
1335 return 1;
1336 }
1337 else
1338 delete_insns_since (last);
1339 }
1340
1341 /* It can't be done in this mode. Can we do it in a wider mode? */
1342
1343 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1344 {
1345 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1346 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1347 {
1348 if (binoptab->handlers[(int) wider_mode].insn_code
1349 != CODE_FOR_nothing)
1350 {
1351 register rtx t0 = gen_reg_rtx (wider_mode);
1352 register rtx t1 = gen_reg_rtx (wider_mode);
1353
1354 if (expand_twoval_binop (binoptab,
1355 convert_to_mode (wider_mode, op0,
1356 unsignedp),
1357 convert_to_mode (wider_mode, op1,
1358 unsignedp),
1359 t0, t1, unsignedp))
1360 {
1361 convert_move (targ0, t0, unsignedp);
1362 convert_move (targ1, t1, unsignedp);
1363 return 1;
1364 }
1365 else
1366 delete_insns_since (last);
1367 }
1368 }
1369 }
1370
1371 delete_insns_since (entry_last);
1372 return 0;
1373 }
1374 \f
1375 /* Generate code to perform an operation specified by UNOPTAB
1376 on operand OP0, with result having machine-mode MODE.
1377
1378 UNSIGNEDP is for the case where we have to widen the operands
1379 to perform the operation. It says to use zero-extension.
1380
1381 If TARGET is nonzero, the value
1382 is generated there, if it is convenient to do so.
1383 In all cases an rtx is returned for the locus of the value;
1384 this may or may not be TARGET. */
1385
1386 rtx
1387 expand_unop (mode, unoptab, op0, target, unsignedp)
1388 enum machine_mode mode;
1389 optab unoptab;
1390 rtx op0;
1391 rtx target;
1392 int unsignedp;
1393 {
1394 enum mode_class class;
1395 enum machine_mode wider_mode;
1396 register rtx temp;
1397 rtx last = get_last_insn ();
1398 rtx pat;
1399
1400 class = GET_MODE_CLASS (mode);
1401
1402 op0 = protect_from_queue (op0, 0);
1403
1404 if (flag_force_mem)
1405 {
1406 op0 = force_not_mem (op0);
1407 }
1408
1409 if (target)
1410 target = protect_from_queue (target, 1);
1411
1412 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1413 {
1414 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1415 enum machine_mode mode0 = insn_operand_mode[icode][1];
1416 rtx xop0 = op0;
1417
1418 if (target)
1419 temp = target;
1420 else
1421 temp = gen_reg_rtx (mode);
1422
1423 if (GET_MODE (xop0) != VOIDmode
1424 && GET_MODE (xop0) != mode0)
1425 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1426
1427 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1428
1429 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1430 xop0 = copy_to_mode_reg (mode0, xop0);
1431
1432 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1433 temp = gen_reg_rtx (mode);
1434
1435 pat = GEN_FCN (icode) (temp, xop0);
1436 if (pat)
1437 {
1438 if (GET_CODE (pat) == SEQUENCE
1439 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1440 {
1441 delete_insns_since (last);
1442 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1443 }
1444
1445 emit_insn (pat);
1446
1447 return temp;
1448 }
1449 else
1450 delete_insns_since (last);
1451 }
1452
1453 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1454
1455 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1456 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1457 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1458 {
1459 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1460 {
1461 rtx xop0 = op0;
1462
1463 /* For certain operations, we need not actually extend
1464 the narrow operand, as long as we will truncate the
1465 results to the same narrowness. But it is faster to
1466 convert a SUBREG due to mode promotion. */
1467
1468 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1469 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1470 && class == MODE_INT
1471 && ! (GET_CODE (xop0) == SUBREG
1472 && SUBREG_PROMOTED_VAR_P (xop0)))
1473 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1474 else
1475 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1476
1477 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1478 unsignedp);
1479
1480 if (temp)
1481 {
1482 if (class != MODE_INT)
1483 {
1484 if (target == 0)
1485 target = gen_reg_rtx (mode);
1486 convert_move (target, temp, 0);
1487 return target;
1488 }
1489 else
1490 return gen_lowpart (mode, temp);
1491 }
1492 else
1493 delete_insns_since (last);
1494 }
1495 }
1496
1497 /* These can be done a word at a time. */
1498 if (unoptab == one_cmpl_optab
1499 && class == MODE_INT
1500 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1501 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1502 {
1503 int i;
1504 rtx insns;
1505
1506 if (target == 0 || target == op0)
1507 target = gen_reg_rtx (mode);
1508
1509 start_sequence ();
1510
1511 /* Do the actual arithmetic. */
1512 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1513 {
1514 rtx target_piece = operand_subword (target, i, 1, mode);
1515 rtx x = expand_unop (word_mode, unoptab,
1516 operand_subword_force (op0, i, mode),
1517 target_piece, unsignedp);
1518 if (target_piece != x)
1519 emit_move_insn (target_piece, x);
1520 }
1521
1522 insns = get_insns ();
1523 end_sequence ();
1524
1525 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1526 gen_rtx (unoptab->code, mode, op0));
1527 return target;
1528 }
1529
1530 /* Open-code the complex negation operation. */
1531 else if (unoptab == neg_optab
1532 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1533 {
1534 rtx target_piece;
1535 rtx x;
1536 rtx seq;
1537
1538 /* Find the correct mode for the real and imaginary parts */
1539 enum machine_mode submode
1540 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1541 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1542 0);
1543
1544 if (submode == BLKmode)
1545 abort ();
1546
1547 if (target == 0)
1548 target = gen_reg_rtx (mode);
1549
1550 start_sequence ();
1551
1552 target_piece = gen_imagpart (submode, target);
1553 x = expand_unop (submode, unoptab,
1554 gen_imagpart (submode, op0),
1555 target_piece, unsignedp);
1556 if (target_piece != x)
1557 emit_move_insn (target_piece, x);
1558
1559 target_piece = gen_realpart (submode, target);
1560 x = expand_unop (submode, unoptab,
1561 gen_realpart (submode, op0),
1562 target_piece, unsignedp);
1563 if (target_piece != x)
1564 emit_move_insn (target_piece, x);
1565
1566 seq = get_insns ();
1567 end_sequence ();
1568
1569 emit_no_conflict_block (seq, target, op0, 0,
1570 gen_rtx (unoptab->code, mode, op0));
1571 return target;
1572 }
1573
1574 /* Now try a library call in this mode. */
1575 if (unoptab->handlers[(int) mode].libfunc)
1576 {
1577 rtx insns;
1578 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1579
1580 start_sequence ();
1581
1582 /* Pass 1 for NO_QUEUE so we don't lose any increments
1583 if the libcall is cse'd or moved. */
1584 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1585 1, mode, 1, op0, mode);
1586 insns = get_insns ();
1587 end_sequence ();
1588
1589 target = gen_reg_rtx (mode);
1590 emit_libcall_block (insns, target, hard_libcall_value (mode),
1591 gen_rtx (unoptab->code, mode, op0));
1592
1593 return target;
1594 }
1595
1596 /* It can't be done in this mode. Can we do it in a wider mode? */
1597
1598 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1599 {
1600 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1601 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1602 {
1603 if ((unoptab->handlers[(int) wider_mode].insn_code
1604 != CODE_FOR_nothing)
1605 || unoptab->handlers[(int) wider_mode].libfunc)
1606 {
1607 rtx xop0 = op0;
1608
1609 /* For certain operations, we need not actually extend
1610 the narrow operand, as long as we will truncate the
1611 results to the same narrowness. */
1612
1613 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1614 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1615 && class == MODE_INT
1616 && ! (GET_CODE (xop0) == SUBREG
1617 && SUBREG_PROMOTED_VAR_P (xop0)))
1618 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1619 else
1620 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1621
1622 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1623 unsignedp);
1624
1625 if (temp)
1626 {
1627 if (class != MODE_INT)
1628 {
1629 if (target == 0)
1630 target = gen_reg_rtx (mode);
1631 convert_move (target, temp, 0);
1632 return target;
1633 }
1634 else
1635 return gen_lowpart (mode, temp);
1636 }
1637 else
1638 delete_insns_since (last);
1639 }
1640 }
1641 }
1642
1643 return 0;
1644 }
1645 \f
1646 /* Emit code to compute the absolute value of OP0, with result to
1647 TARGET if convenient. (TARGET may be 0.) The return value says
1648 where the result actually is to be found.
1649
1650 MODE is the mode of the operand; the mode of the result is
1651 different but can be deduced from MODE.
1652
1653 UNSIGNEDP is relevant for complex integer modes. */
1654
1655 rtx
1656 expand_complex_abs (mode, op0, target, unsignedp)
1657 enum machine_mode mode;
1658 rtx op0;
1659 rtx target;
1660 int unsignedp;
1661 {
1662 enum mode_class class = GET_MODE_CLASS (mode);
1663 enum machine_mode wider_mode;
1664 register rtx temp;
1665 rtx entry_last = get_last_insn ();
1666 rtx last;
1667 rtx pat;
1668
1669 /* Find the correct mode for the real and imaginary parts. */
1670 enum machine_mode submode
1671 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1672 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1673 0);
1674
1675 if (submode == BLKmode)
1676 abort ();
1677
1678 op0 = protect_from_queue (op0, 0);
1679
1680 if (flag_force_mem)
1681 {
1682 op0 = force_not_mem (op0);
1683 }
1684
1685 last = get_last_insn ();
1686
1687 if (target)
1688 target = protect_from_queue (target, 1);
1689
1690 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1691 {
1692 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1693 enum machine_mode mode0 = insn_operand_mode[icode][1];
1694 rtx xop0 = op0;
1695
1696 if (target)
1697 temp = target;
1698 else
1699 temp = gen_reg_rtx (submode);
1700
1701 if (GET_MODE (xop0) != VOIDmode
1702 && GET_MODE (xop0) != mode0)
1703 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1704
1705 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1706
1707 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1708 xop0 = copy_to_mode_reg (mode0, xop0);
1709
1710 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1711 temp = gen_reg_rtx (submode);
1712
1713 pat = GEN_FCN (icode) (temp, xop0);
1714 if (pat)
1715 {
1716 if (GET_CODE (pat) == SEQUENCE
1717 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1718 {
1719 delete_insns_since (last);
1720 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
1721 }
1722
1723 emit_insn (pat);
1724
1725 return temp;
1726 }
1727 else
1728 delete_insns_since (last);
1729 }
1730
1731 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1732
1733 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1734 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1735 {
1736 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1737 {
1738 rtx xop0 = op0;
1739
1740 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1741 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1742
1743 if (temp)
1744 {
1745 if (class != MODE_COMPLEX_INT)
1746 {
1747 if (target == 0)
1748 target = gen_reg_rtx (submode);
1749 convert_move (target, temp, 0);
1750 return target;
1751 }
1752 else
1753 return gen_lowpart (submode, temp);
1754 }
1755 else
1756 delete_insns_since (last);
1757 }
1758 }
1759
1760 /* Open-code the complex absolute-value operation
1761 if we can open-code sqrt. Otherwise it's not worth while. */
1762 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1763 {
1764 rtx real, imag, total;
1765
1766 real = gen_realpart (submode, op0);
1767 imag = gen_imagpart (submode, op0);
1768 /* Square both parts. */
1769 real = expand_mult (mode, real, real, NULL_RTX, 0);
1770 imag = expand_mult (mode, imag, imag, NULL_RTX, 0);
1771 /* Sum the parts. */
1772 total = expand_binop (submode, add_optab, real, imag, 0,
1773 0, OPTAB_LIB_WIDEN);
1774 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1775 target = expand_unop (submode, sqrt_optab, total, target, 0);
1776 if (target == 0)
1777 delete_insns_since (last);
1778 else
1779 return target;
1780 }
1781
1782 /* Now try a library call in this mode. */
1783 if (abs_optab->handlers[(int) mode].libfunc)
1784 {
1785 rtx insns;
1786 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
1787
1788 start_sequence ();
1789
1790 /* Pass 1 for NO_QUEUE so we don't lose any increments
1791 if the libcall is cse'd or moved. */
1792 emit_library_call (abs_optab->handlers[(int) mode].libfunc,
1793 1, mode, 1, op0, mode);
1794 insns = get_insns ();
1795 end_sequence ();
1796
1797 target = gen_reg_rtx (submode);
1798 emit_libcall_block (insns, target, hard_libcall_value (submode),
1799 gen_rtx (abs_optab->code, mode, op0));
1800
1801 return target;
1802 }
1803
1804 /* It can't be done in this mode. Can we do it in a wider mode? */
1805
1806 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1807 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1808 {
1809 if ((abs_optab->handlers[(int) wider_mode].insn_code
1810 != CODE_FOR_nothing)
1811 || abs_optab->handlers[(int) wider_mode].libfunc)
1812 {
1813 rtx xop0 = op0;
1814
1815 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1816
1817 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1818
1819 if (temp)
1820 {
1821 if (class != MODE_COMPLEX_INT)
1822 {
1823 if (target == 0)
1824 target = gen_reg_rtx (submode);
1825 convert_move (target, temp, 0);
1826 return target;
1827 }
1828 else
1829 return gen_lowpart (submode, temp);
1830 }
1831 else
1832 delete_insns_since (last);
1833 }
1834 }
1835
1836 delete_insns_since (entry_last);
1837 return 0;
1838 }
1839 \f
1840 /* Generate an instruction whose insn-code is INSN_CODE,
1841 with two operands: an output TARGET and an input OP0.
1842 TARGET *must* be nonzero, and the output is always stored there.
1843 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1844 the value that is stored into TARGET. */
1845
1846 void
1847 emit_unop_insn (icode, target, op0, code)
1848 int icode;
1849 rtx target;
1850 rtx op0;
1851 enum rtx_code code;
1852 {
1853 register rtx temp;
1854 enum machine_mode mode0 = insn_operand_mode[icode][1];
1855 rtx pat;
1856
1857 temp = target = protect_from_queue (target, 1);
1858
1859 op0 = protect_from_queue (op0, 0);
1860
1861 if (flag_force_mem)
1862 op0 = force_not_mem (op0);
1863
1864 /* Now, if insn does not accept our operands, put them into pseudos. */
1865
1866 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1867 op0 = copy_to_mode_reg (mode0, op0);
1868
1869 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1870 || (flag_force_mem && GET_CODE (temp) == MEM))
1871 temp = gen_reg_rtx (GET_MODE (temp));
1872
1873 pat = GEN_FCN (icode) (temp, op0);
1874
1875 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1876 add_equal_note (pat, temp, code, op0, NULL_RTX);
1877
1878 emit_insn (pat);
1879
1880 if (temp != target)
1881 emit_move_insn (target, temp);
1882 }
1883 \f
1884 /* Emit code to perform a series of operations on a multi-word quantity, one
1885 word at a time.
1886
1887 Such a block is preceded by a CLOBBER of the output, consists of multiple
1888 insns, each setting one word of the output, and followed by a SET copying
1889 the output to itself.
1890
1891 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1892 note indicating that it doesn't conflict with the (also multi-word)
1893 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1894 notes.
1895
1896 INSNS is a block of code generated to perform the operation, not including
1897 the CLOBBER and final copy. All insns that compute intermediate values
1898 are first emitted, followed by the block as described above. Only
1899 INSNs are allowed in the block; no library calls or jumps may be
1900 present.
1901
1902 TARGET, OP0, and OP1 are the output and inputs of the operations,
1903 respectively. OP1 may be zero for a unary operation.
1904
1905 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1906 on the last insn.
1907
1908 If TARGET is not a register, INSNS is simply emitted with no special
1909 processing.
1910
1911 The final insn emitted is returned. */
1912
1913 rtx
1914 emit_no_conflict_block (insns, target, op0, op1, equiv)
1915 rtx insns;
1916 rtx target;
1917 rtx op0, op1;
1918 rtx equiv;
1919 {
1920 rtx prev, next, first, last, insn;
1921
1922 if (GET_CODE (target) != REG || reload_in_progress)
1923 return emit_insns (insns);
1924
1925 /* First emit all insns that do not store into words of the output and remove
1926 these from the list. */
1927 for (insn = insns; insn; insn = next)
1928 {
1929 rtx set = 0;
1930 int i;
1931
1932 next = NEXT_INSN (insn);
1933
1934 if (GET_CODE (insn) != INSN)
1935 abort ();
1936
1937 if (GET_CODE (PATTERN (insn)) == SET)
1938 set = PATTERN (insn);
1939 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1940 {
1941 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1942 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1943 {
1944 set = XVECEXP (PATTERN (insn), 0, i);
1945 break;
1946 }
1947 }
1948
1949 if (set == 0)
1950 abort ();
1951
1952 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1953 {
1954 if (PREV_INSN (insn))
1955 NEXT_INSN (PREV_INSN (insn)) = next;
1956 else
1957 insns = next;
1958
1959 if (next)
1960 PREV_INSN (next) = PREV_INSN (insn);
1961
1962 add_insn (insn);
1963 }
1964 }
1965
1966 prev = get_last_insn ();
1967
1968 /* Now write the CLOBBER of the output, followed by the setting of each
1969 of the words, followed by the final copy. */
1970 if (target != op0 && target != op1)
1971 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1972
1973 for (insn = insns; insn; insn = next)
1974 {
1975 next = NEXT_INSN (insn);
1976 add_insn (insn);
1977
1978 if (op1 && GET_CODE (op1) == REG)
1979 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1980 REG_NOTES (insn));
1981
1982 if (op0 && GET_CODE (op0) == REG)
1983 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1984 REG_NOTES (insn));
1985 }
1986
1987 last = emit_move_insn (target, target);
1988 if (equiv)
1989 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1990
1991 if (prev == 0)
1992 first = get_insns ();
1993 else
1994 first = NEXT_INSN (prev);
1995
1996 /* Encapsulate the block so it gets manipulated as a unit. */
1997 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1998 REG_NOTES (first));
1999 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2000
2001 return last;
2002 }
2003 \f
2004 /* Emit code to make a call to a constant function or a library call.
2005
2006 INSNS is a list containing all insns emitted in the call.
2007 These insns leave the result in RESULT. Our block is to copy RESULT
2008 to TARGET, which is logically equivalent to EQUIV.
2009
2010 We first emit any insns that set a pseudo on the assumption that these are
2011 loading constants into registers; doing so allows them to be safely cse'ed
2012 between blocks. Then we emit all the other insns in the block, followed by
2013 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2014 note with an operand of EQUIV.
2015
2016 Moving assignments to pseudos outside of the block is done to improve
2017 the generated code, but is not required to generate correct code,
2018 hence being unable to move an assignment is not grounds for not making
2019 a libcall block. There are two reasons why it is safe to leave these
2020 insns inside the block: First, we know that these pseudos cannot be
2021 used in generated RTL outside the block since they are created for
2022 temporary purposes within the block. Second, CSE will not record the
2023 values of anything set inside a libcall block, so we know they must
2024 be dead at the end of the block.
2025
2026 Except for the first group of insns (the ones setting pseudos), the
2027 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2028
2029 void
2030 emit_libcall_block (insns, target, result, equiv)
2031 rtx insns;
2032 rtx target;
2033 rtx result;
2034 rtx equiv;
2035 {
2036 rtx prev, next, first, last, insn;
2037
2038 /* First emit all insns that set pseudos. Remove them from the list as
2039 we go. Avoid insns that set pseudo which were referenced in previous
2040 insns. These can be generated by move_by_pieces, for example,
2041 to update an address. */
2042
2043 for (insn = insns; insn; insn = next)
2044 {
2045 rtx set = single_set (insn);
2046
2047 next = NEXT_INSN (insn);
2048
2049 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2050 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2051 && (insn == insns
2052 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2053 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
2054 {
2055 if (PREV_INSN (insn))
2056 NEXT_INSN (PREV_INSN (insn)) = next;
2057 else
2058 insns = next;
2059
2060 if (next)
2061 PREV_INSN (next) = PREV_INSN (insn);
2062
2063 add_insn (insn);
2064 }
2065 }
2066
2067 prev = get_last_insn ();
2068
2069 /* Write the remaining insns followed by the final copy. */
2070
2071 for (insn = insns; insn; insn = next)
2072 {
2073 next = NEXT_INSN (insn);
2074
2075 add_insn (insn);
2076 }
2077
2078 last = emit_move_insn (target, result);
2079 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2080
2081 if (prev == 0)
2082 first = get_insns ();
2083 else
2084 first = NEXT_INSN (prev);
2085
2086 /* Encapsulate the block so it gets manipulated as a unit. */
2087 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2088 REG_NOTES (first));
2089 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2090 }
2091 \f
2092 /* Generate code to store zero in X. */
2093
2094 void
2095 emit_clr_insn (x)
2096 rtx x;
2097 {
2098 emit_move_insn (x, const0_rtx);
2099 }
2100
2101 /* Generate code to store 1 in X
2102 assuming it contains zero beforehand. */
2103
2104 void
2105 emit_0_to_1_insn (x)
2106 rtx x;
2107 {
2108 emit_move_insn (x, const1_rtx);
2109 }
2110
2111 /* Generate code to compare X with Y
2112 so that the condition codes are set.
2113
2114 MODE is the mode of the inputs (in case they are const_int).
2115 UNSIGNEDP nonzero says that X and Y are unsigned;
2116 this matters if they need to be widened.
2117
2118 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2119 and ALIGN specifies the known shared alignment of X and Y.
2120
2121 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2122 It is ignored for fixed-point and block comparisons;
2123 it is used only for floating-point comparisons. */
2124
2125 void
2126 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2127 rtx x, y;
2128 enum rtx_code comparison;
2129 rtx size;
2130 enum machine_mode mode;
2131 int unsignedp;
2132 int align;
2133 {
2134 enum mode_class class;
2135 enum machine_mode wider_mode;
2136
2137 class = GET_MODE_CLASS (mode);
2138
2139 /* They could both be VOIDmode if both args are immediate constants,
2140 but we should fold that at an earlier stage.
2141 With no special code here, this will call abort,
2142 reminding the programmer to implement such folding. */
2143
2144 if (mode != BLKmode && flag_force_mem)
2145 {
2146 x = force_not_mem (x);
2147 y = force_not_mem (y);
2148 }
2149
2150 /* If we are inside an appropriately-short loop and one operand is an
2151 expensive constant, force it into a register. */
2152 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2153 x = force_reg (mode, x);
2154
2155 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2156 y = force_reg (mode, y);
2157
2158 /* Don't let both operands fail to indicate the mode. */
2159 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2160 x = force_reg (mode, x);
2161
2162 /* Handle all BLKmode compares. */
2163
2164 if (mode == BLKmode)
2165 {
2166 emit_queue ();
2167 x = protect_from_queue (x, 0);
2168 y = protect_from_queue (y, 0);
2169
2170 if (size == 0)
2171 abort ();
2172 #ifdef HAVE_cmpstrqi
2173 if (HAVE_cmpstrqi
2174 && GET_CODE (size) == CONST_INT
2175 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2176 {
2177 enum machine_mode result_mode
2178 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2179 rtx result = gen_reg_rtx (result_mode);
2180 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2181 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2182 result_mode, 0, 0);
2183 }
2184 else
2185 #endif
2186 #ifdef HAVE_cmpstrhi
2187 if (HAVE_cmpstrhi
2188 && GET_CODE (size) == CONST_INT
2189 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2190 {
2191 enum machine_mode result_mode
2192 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2193 rtx result = gen_reg_rtx (result_mode);
2194 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2195 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2196 result_mode, 0, 0);
2197 }
2198 else
2199 #endif
2200 #ifdef HAVE_cmpstrsi
2201 if (HAVE_cmpstrsi)
2202 {
2203 enum machine_mode result_mode
2204 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2205 rtx result = gen_reg_rtx (result_mode);
2206 size = protect_from_queue (size, 0);
2207 emit_insn (gen_cmpstrsi (result, x, y,
2208 convert_to_mode (SImode, size, 1),
2209 GEN_INT (align)));
2210 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2211 result_mode, 0, 0);
2212 }
2213 else
2214 #endif
2215 {
2216 #ifdef TARGET_MEM_FUNCTIONS
2217 emit_library_call (memcmp_libfunc, 0,
2218 TYPE_MODE (integer_type_node), 3,
2219 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2220 size, Pmode);
2221 #else
2222 emit_library_call (bcmp_libfunc, 0,
2223 TYPE_MODE (integer_type_node), 3,
2224 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2225 size, Pmode);
2226 #endif
2227 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2228 const0_rtx, comparison, NULL_RTX,
2229 TYPE_MODE (integer_type_node), 0, 0);
2230 }
2231 return;
2232 }
2233
2234 /* Handle some compares against zero. */
2235
2236 if (y == CONST0_RTX (mode)
2237 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2238 {
2239 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2240
2241 emit_queue ();
2242 x = protect_from_queue (x, 0);
2243 y = protect_from_queue (y, 0);
2244
2245 /* Now, if insn does accept these operands, put them into pseudos. */
2246 if (! (*insn_operand_predicate[icode][0])
2247 (x, insn_operand_mode[icode][0]))
2248 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2249
2250 emit_insn (GEN_FCN (icode) (x));
2251 return;
2252 }
2253
2254 /* Handle compares for which there is a directly suitable insn. */
2255
2256 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2257 {
2258 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2259
2260 emit_queue ();
2261 x = protect_from_queue (x, 0);
2262 y = protect_from_queue (y, 0);
2263
2264 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2265 if (! (*insn_operand_predicate[icode][0])
2266 (x, insn_operand_mode[icode][0]))
2267 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2268
2269 if (! (*insn_operand_predicate[icode][1])
2270 (y, insn_operand_mode[icode][1]))
2271 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2272
2273 emit_insn (GEN_FCN (icode) (x, y));
2274 return;
2275 }
2276
2277 /* Try widening if we can find a direct insn that way. */
2278
2279 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2280 {
2281 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2282 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2283 {
2284 if (cmp_optab->handlers[(int) wider_mode].insn_code
2285 != CODE_FOR_nothing)
2286 {
2287 x = protect_from_queue (x, 0);
2288 y = protect_from_queue (y, 0);
2289 x = convert_to_mode (wider_mode, x, unsignedp);
2290 y = convert_to_mode (wider_mode, y, unsignedp);
2291 emit_cmp_insn (x, y, comparison, NULL_RTX,
2292 wider_mode, unsignedp, align);
2293 return;
2294 }
2295 }
2296 }
2297
2298 /* Handle a lib call just for the mode we are using. */
2299
2300 if (cmp_optab->handlers[(int) mode].libfunc
2301 && class != MODE_FLOAT)
2302 {
2303 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2304 /* If we want unsigned, and this mode has a distinct unsigned
2305 comparison routine, use that. */
2306 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2307 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2308
2309 emit_library_call (libfunc, 1,
2310 word_mode, 2, x, mode, y, mode);
2311
2312 /* Integer comparison returns a result that must be compared against 1,
2313 so that even if we do an unsigned compare afterward,
2314 there is still a value that can represent the result "less than". */
2315
2316 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2317 comparison, NULL_RTX, word_mode, unsignedp, 0);
2318 return;
2319 }
2320
2321 if (class == MODE_FLOAT)
2322 emit_float_lib_cmp (x, y, comparison);
2323
2324 else
2325 abort ();
2326 }
2327
2328 /* Nonzero if a compare of mode MODE can be done straightforwardly
2329 (without splitting it into pieces). */
2330
2331 int
2332 can_compare_p (mode)
2333 enum machine_mode mode;
2334 {
2335 do
2336 {
2337 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2338 return 1;
2339 mode = GET_MODE_WIDER_MODE (mode);
2340 } while (mode != VOIDmode);
2341
2342 return 0;
2343 }
2344 \f
2345 /* Emit a library call comparison between floating point X and Y.
2346 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2347
2348 static void
2349 emit_float_lib_cmp (x, y, comparison)
2350 rtx x, y;
2351 enum rtx_code comparison;
2352 {
2353 enum machine_mode mode = GET_MODE (x);
2354 rtx libfunc;
2355
2356 if (mode == SFmode)
2357 switch (comparison)
2358 {
2359 case EQ:
2360 libfunc = eqsf2_libfunc;
2361 break;
2362
2363 case NE:
2364 libfunc = nesf2_libfunc;
2365 break;
2366
2367 case GT:
2368 libfunc = gtsf2_libfunc;
2369 break;
2370
2371 case GE:
2372 libfunc = gesf2_libfunc;
2373 break;
2374
2375 case LT:
2376 libfunc = ltsf2_libfunc;
2377 break;
2378
2379 case LE:
2380 libfunc = lesf2_libfunc;
2381 break;
2382 }
2383 else if (mode == DFmode)
2384 switch (comparison)
2385 {
2386 case EQ:
2387 libfunc = eqdf2_libfunc;
2388 break;
2389
2390 case NE:
2391 libfunc = nedf2_libfunc;
2392 break;
2393
2394 case GT:
2395 libfunc = gtdf2_libfunc;
2396 break;
2397
2398 case GE:
2399 libfunc = gedf2_libfunc;
2400 break;
2401
2402 case LT:
2403 libfunc = ltdf2_libfunc;
2404 break;
2405
2406 case LE:
2407 libfunc = ledf2_libfunc;
2408 break;
2409 }
2410 else if (mode == XFmode)
2411 switch (comparison)
2412 {
2413 case EQ:
2414 libfunc = eqxf2_libfunc;
2415 break;
2416
2417 case NE:
2418 libfunc = nexf2_libfunc;
2419 break;
2420
2421 case GT:
2422 libfunc = gtxf2_libfunc;
2423 break;
2424
2425 case GE:
2426 libfunc = gexf2_libfunc;
2427 break;
2428
2429 case LT:
2430 libfunc = ltxf2_libfunc;
2431 break;
2432
2433 case LE:
2434 libfunc = lexf2_libfunc;
2435 break;
2436 }
2437 else if (mode == TFmode)
2438 switch (comparison)
2439 {
2440 case EQ:
2441 libfunc = eqtf2_libfunc;
2442 break;
2443
2444 case NE:
2445 libfunc = netf2_libfunc;
2446 break;
2447
2448 case GT:
2449 libfunc = gttf2_libfunc;
2450 break;
2451
2452 case GE:
2453 libfunc = getf2_libfunc;
2454 break;
2455
2456 case LT:
2457 libfunc = lttf2_libfunc;
2458 break;
2459
2460 case LE:
2461 libfunc = letf2_libfunc;
2462 break;
2463 }
2464 else
2465 {
2466 enum machine_mode wider_mode;
2467
2468 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2469 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2470 {
2471 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2472 != CODE_FOR_nothing)
2473 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2474 {
2475 x = protect_from_queue (x, 0);
2476 y = protect_from_queue (y, 0);
2477 x = convert_to_mode (wider_mode, x, 0);
2478 y = convert_to_mode (wider_mode, y, 0);
2479 emit_float_lib_cmp (x, y, comparison);
2480 return;
2481 }
2482 }
2483 abort ();
2484 }
2485
2486 emit_library_call (libfunc, 1,
2487 word_mode, 2, x, mode, y, mode);
2488
2489 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2490 NULL_RTX, word_mode, 0, 0);
2491 }
2492 \f
2493 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2494
2495 void
2496 emit_indirect_jump (loc)
2497 rtx loc;
2498 {
2499 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2500 (loc, Pmode)))
2501 loc = copy_to_mode_reg (Pmode, loc);
2502
2503 emit_jump_insn (gen_indirect_jump (loc));
2504 emit_barrier ();
2505 }
2506 \f
2507 /* These three functions generate an insn body and return it
2508 rather than emitting the insn.
2509
2510 They do not protect from queued increments,
2511 because they may be used 1) in protect_from_queue itself
2512 and 2) in other passes where there is no queue. */
2513
2514 /* Generate and return an insn body to add Y to X. */
2515
2516 rtx
2517 gen_add2_insn (x, y)
2518 rtx x, y;
2519 {
2520 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2521
2522 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2523 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2524 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2525 abort ();
2526
2527 return (GEN_FCN (icode) (x, x, y));
2528 }
2529
2530 int
2531 have_add2_insn (mode)
2532 enum machine_mode mode;
2533 {
2534 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2535 }
2536
2537 /* Generate and return an insn body to subtract Y from X. */
2538
2539 rtx
2540 gen_sub2_insn (x, y)
2541 rtx x, y;
2542 {
2543 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2544
2545 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2546 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2547 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2548 abort ();
2549
2550 return (GEN_FCN (icode) (x, x, y));
2551 }
2552
2553 int
2554 have_sub2_insn (mode)
2555 enum machine_mode mode;
2556 {
2557 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2558 }
2559
2560 /* Generate the body of an instruction to copy Y into X.
2561 It may be a SEQUENCE, if one insn isn't enough. */
2562
2563 rtx
2564 gen_move_insn (x, y)
2565 rtx x, y;
2566 {
2567 register enum machine_mode mode = GET_MODE (x);
2568 enum insn_code insn_code;
2569 rtx seq;
2570
2571 if (mode == VOIDmode)
2572 mode = GET_MODE (y);
2573
2574 insn_code = mov_optab->handlers[(int) mode].insn_code;
2575
2576 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2577 find a mode to do it in. If we have a movcc, use it. Otherwise,
2578 find the MODE_INT mode of the same width. */
2579
2580 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2581 {
2582 enum machine_mode tmode = VOIDmode;
2583 rtx x1 = x, y1 = y;
2584
2585 if (mode != CCmode
2586 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2587 tmode = CCmode;
2588 else
2589 for (tmode = QImode; tmode != VOIDmode;
2590 tmode = GET_MODE_WIDER_MODE (tmode))
2591 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2592 break;
2593
2594 if (tmode == VOIDmode)
2595 abort ();
2596
2597 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2598 may call change_address which is not appropriate if we were
2599 called when a reload was in progress. We don't have to worry
2600 about changing the address since the size in bytes is supposed to
2601 be the same. Copy the MEM to change the mode and move any
2602 substitutions from the old MEM to the new one. */
2603
2604 if (reload_in_progress)
2605 {
2606 x = gen_lowpart_common (tmode, x1);
2607 if (x == 0 && GET_CODE (x1) == MEM)
2608 {
2609 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2610 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2611 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2612 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2613 copy_replacements (x1, x);
2614 }
2615
2616 y = gen_lowpart_common (tmode, y1);
2617 if (y == 0 && GET_CODE (y1) == MEM)
2618 {
2619 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2620 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2621 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2622 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2623 copy_replacements (y1, y);
2624 }
2625 }
2626 else
2627 {
2628 x = gen_lowpart (tmode, x);
2629 y = gen_lowpart (tmode, y);
2630 }
2631
2632 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2633 return (GEN_FCN (insn_code) (x, y));
2634 }
2635
2636 start_sequence ();
2637 emit_move_insn_1 (x, y);
2638 seq = gen_sequence ();
2639 end_sequence ();
2640 return seq;
2641 }
2642 \f
2643 /* Tables of patterns for extending one integer mode to another. */
2644 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2645
2646 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2647 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2648 no such operation exists, CODE_FOR_nothing will be returned. */
2649
2650 enum insn_code
2651 can_extend_p (to_mode, from_mode, unsignedp)
2652 enum machine_mode to_mode, from_mode;
2653 int unsignedp;
2654 {
2655 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2656 }
2657
2658 /* Generate the body of an insn to extend Y (with mode MFROM)
2659 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2660
2661 rtx
2662 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2663 rtx x, y;
2664 enum machine_mode mto, mfrom;
2665 int unsignedp;
2666 {
2667 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2668 }
2669
2670 static void
2671 init_extends ()
2672 {
2673 enum insn_code *p;
2674
2675 for (p = extendtab[0][0];
2676 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2677 p++)
2678 *p = CODE_FOR_nothing;
2679
2680 #ifdef HAVE_extendditi2
2681 if (HAVE_extendditi2)
2682 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2683 #endif
2684 #ifdef HAVE_extendsiti2
2685 if (HAVE_extendsiti2)
2686 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2687 #endif
2688 #ifdef HAVE_extendhiti2
2689 if (HAVE_extendhiti2)
2690 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2691 #endif
2692 #ifdef HAVE_extendqiti2
2693 if (HAVE_extendqiti2)
2694 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2695 #endif
2696 #ifdef HAVE_extendsidi2
2697 if (HAVE_extendsidi2)
2698 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2699 #endif
2700 #ifdef HAVE_extendhidi2
2701 if (HAVE_extendhidi2)
2702 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2703 #endif
2704 #ifdef HAVE_extendqidi2
2705 if (HAVE_extendqidi2)
2706 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2707 #endif
2708 #ifdef HAVE_extendhisi2
2709 if (HAVE_extendhisi2)
2710 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2711 #endif
2712 #ifdef HAVE_extendqisi2
2713 if (HAVE_extendqisi2)
2714 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2715 #endif
2716 #ifdef HAVE_extendqihi2
2717 if (HAVE_extendqihi2)
2718 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2719 #endif
2720
2721 #ifdef HAVE_zero_extendditi2
2722 if (HAVE_zero_extendsiti2)
2723 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2724 #endif
2725 #ifdef HAVE_zero_extendsiti2
2726 if (HAVE_zero_extendsiti2)
2727 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2728 #endif
2729 #ifdef HAVE_zero_extendhiti2
2730 if (HAVE_zero_extendhiti2)
2731 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2732 #endif
2733 #ifdef HAVE_zero_extendqiti2
2734 if (HAVE_zero_extendqiti2)
2735 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2736 #endif
2737 #ifdef HAVE_zero_extendsidi2
2738 if (HAVE_zero_extendsidi2)
2739 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2740 #endif
2741 #ifdef HAVE_zero_extendhidi2
2742 if (HAVE_zero_extendhidi2)
2743 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2744 #endif
2745 #ifdef HAVE_zero_extendqidi2
2746 if (HAVE_zero_extendqidi2)
2747 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2748 #endif
2749 #ifdef HAVE_zero_extendhisi2
2750 if (HAVE_zero_extendhisi2)
2751 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2752 #endif
2753 #ifdef HAVE_zero_extendqisi2
2754 if (HAVE_zero_extendqisi2)
2755 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2756 #endif
2757 #ifdef HAVE_zero_extendqihi2
2758 if (HAVE_zero_extendqihi2)
2759 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2760 #endif
2761 }
2762 \f
2763 /* can_fix_p and can_float_p say whether the target machine
2764 can directly convert a given fixed point type to
2765 a given floating point type, or vice versa.
2766 The returned value is the CODE_FOR_... value to use,
2767 or CODE_FOR_nothing if these modes cannot be directly converted. */
2768
2769 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2770 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2771 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2772
2773 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2774 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2775
2776 static enum insn_code
2777 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2778 enum machine_mode fltmode, fixmode;
2779 int unsignedp;
2780 int *truncp_ptr;
2781 {
2782 *truncp_ptr = 0;
2783 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2784 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2785
2786 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2787 {
2788 *truncp_ptr = 1;
2789 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2790 }
2791 return CODE_FOR_nothing;
2792 }
2793
2794 static enum insn_code
2795 can_float_p (fltmode, fixmode, unsignedp)
2796 enum machine_mode fixmode, fltmode;
2797 int unsignedp;
2798 {
2799 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2800 }
2801
2802 void
2803 init_fixtab ()
2804 {
2805 enum insn_code *p;
2806 for (p = fixtab[0][0];
2807 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2808 p++)
2809 *p = CODE_FOR_nothing;
2810 for (p = fixtrunctab[0][0];
2811 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2812 p++)
2813 *p = CODE_FOR_nothing;
2814
2815 #ifdef HAVE_fixqfqi2
2816 if (HAVE_fixqfqi2)
2817 fixtab[(int) QFmode][(int) QImode][0] = CODE_FOR_fixqfqi2;
2818 #endif
2819 #ifdef HAVE_fixhfqi2
2820 if (HAVE_fixhfqi2)
2821 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixhfqi2;
2822 #endif
2823 #ifdef HAVE_fixhfhi2
2824 if (HAVE_fixhfhi2)
2825 fixtab[(int) HFmode][(int) HImode][0] = CODE_FOR_fixhfhi2;
2826 #endif
2827 #ifdef HAVE_fixsfqi2
2828 if (HAVE_fixsfqi2)
2829 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2830 #endif
2831 #ifdef HAVE_fixsfhi2
2832 if (HAVE_fixsfhi2)
2833 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2834 #endif
2835 #ifdef HAVE_fixsfsi2
2836 if (HAVE_fixsfsi2)
2837 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2838 #endif
2839 #ifdef HAVE_fixsfdi2
2840 if (HAVE_fixsfdi2)
2841 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2842 #endif
2843
2844 #ifdef HAVE_fixdfqi2
2845 if (HAVE_fixdfqi2)
2846 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2847 #endif
2848 #ifdef HAVE_fixdfhi2
2849 if (HAVE_fixdfhi2)
2850 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2851 #endif
2852 #ifdef HAVE_fixdfsi2
2853 if (HAVE_fixdfsi2)
2854 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2855 #endif
2856 #ifdef HAVE_fixdfdi2
2857 if (HAVE_fixdfdi2)
2858 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2859 #endif
2860 #ifdef HAVE_fixdfti2
2861 if (HAVE_fixdfti2)
2862 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2863 #endif
2864
2865 #ifdef HAVE_fixxfqi2
2866 if (HAVE_fixxfqi2)
2867 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2868 #endif
2869 #ifdef HAVE_fixxfhi2
2870 if (HAVE_fixxfhi2)
2871 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2872 #endif
2873 #ifdef HAVE_fixxfsi2
2874 if (HAVE_fixxfsi2)
2875 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2876 #endif
2877 #ifdef HAVE_fixxfdi2
2878 if (HAVE_fixxfdi2)
2879 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2880 #endif
2881 #ifdef HAVE_fixxfti2
2882 if (HAVE_fixxfti2)
2883 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2884 #endif
2885
2886 #ifdef HAVE_fixtfqi2
2887 if (HAVE_fixtfqi2)
2888 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2889 #endif
2890 #ifdef HAVE_fixtfhi2
2891 if (HAVE_fixtfhi2)
2892 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2893 #endif
2894 #ifdef HAVE_fixtfsi2
2895 if (HAVE_fixtfsi2)
2896 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2897 #endif
2898 #ifdef HAVE_fixtfdi2
2899 if (HAVE_fixtfdi2)
2900 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2901 #endif
2902 #ifdef HAVE_fixtfti2
2903 if (HAVE_fixtfti2)
2904 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2905 #endif
2906
2907 #ifdef HAVE_fixunsqfqi2
2908 if (HAVE_fixunsqfqi2)
2909 fixtab[(int) QFmode][(int) QImode][1] = CODE_FOR_fixunsqfqi2;
2910 #endif
2911 #ifdef HAVE_fixunshfqi2
2912 if (HAVE_fixunshfqi2)
2913 fixtab[(int) HFmode][(int) QImode][1] = CODE_FOR_fixunshfqi2;
2914 #endif
2915 #ifdef HAVE_fixunshfhi2
2916 if (HAVE_fixunshfhi2)
2917 fixtab[(int) HFmode][(int) HImode][1] = CODE_FOR_fixunshfhi2;
2918 #endif
2919
2920 #ifdef HAVE_fixunssfqi2
2921 if (HAVE_fixunssfqi2)
2922 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2923 #endif
2924 #ifdef HAVE_fixunssfhi2
2925 if (HAVE_fixunssfhi2)
2926 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2927 #endif
2928 #ifdef HAVE_fixunssfsi2
2929 if (HAVE_fixunssfsi2)
2930 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2931 #endif
2932 #ifdef HAVE_fixunssfdi2
2933 if (HAVE_fixunssfdi2)
2934 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2935 #endif
2936
2937 #ifdef HAVE_fixunsdfqi2
2938 if (HAVE_fixunsdfqi2)
2939 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2940 #endif
2941 #ifdef HAVE_fixunsdfhi2
2942 if (HAVE_fixunsdfhi2)
2943 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2944 #endif
2945 #ifdef HAVE_fixunsdfsi2
2946 if (HAVE_fixunsdfsi2)
2947 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2948 #endif
2949 #ifdef HAVE_fixunsdfdi2
2950 if (HAVE_fixunsdfdi2)
2951 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2952 #endif
2953 #ifdef HAVE_fixunsdfti2
2954 if (HAVE_fixunsdfti2)
2955 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2956 #endif
2957
2958 #ifdef HAVE_fixunsxfqi2
2959 if (HAVE_fixunsxfqi2)
2960 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2961 #endif
2962 #ifdef HAVE_fixunsxfhi2
2963 if (HAVE_fixunsxfhi2)
2964 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2965 #endif
2966 #ifdef HAVE_fixunsxfsi2
2967 if (HAVE_fixunsxfsi2)
2968 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2969 #endif
2970 #ifdef HAVE_fixunsxfdi2
2971 if (HAVE_fixunsxfdi2)
2972 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2973 #endif
2974 #ifdef HAVE_fixunsxfti2
2975 if (HAVE_fixunsxfti2)
2976 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2977 #endif
2978
2979 #ifdef HAVE_fixunstfqi2
2980 if (HAVE_fixunstfqi2)
2981 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2982 #endif
2983 #ifdef HAVE_fixunstfhi2
2984 if (HAVE_fixunstfhi2)
2985 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2986 #endif
2987 #ifdef HAVE_fixunstfsi2
2988 if (HAVE_fixunstfsi2)
2989 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2990 #endif
2991 #ifdef HAVE_fixunstfdi2
2992 if (HAVE_fixunstfdi2)
2993 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2994 #endif
2995 #ifdef HAVE_fixunstfti2
2996 if (HAVE_fixunstfti2)
2997 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2998 #endif
2999
3000 #ifdef HAVE_fix_truncqfqi2
3001 if (HAVE_fix_truncqfqi2)
3002 fixtrunctab[(int) QFmode][(int) QImode][0] = CODE_FOR_fix_truncqfqi2;
3003 #endif
3004 #ifdef HAVE_fix_trunchfqi2
3005 if (HAVE_fix_trunchfqi2)
3006 fixtrunctab[(int) HFmode][(int) QImode][0] = CODE_FOR_fix_trunchfqi2;
3007 #endif
3008 #ifdef HAVE_fix_trunchfhi2
3009 if (HAVE_fix_trunchfhi2)
3010 fixtrunctab[(int) HFmode][(int) HImode][0] = CODE_FOR_fix_trunchfhi2;
3011 #endif
3012 #ifdef HAVE_fix_truncsfqi2
3013 if (HAVE_fix_truncsfqi2)
3014 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
3015 #endif
3016 #ifdef HAVE_fix_truncsfhi2
3017 if (HAVE_fix_truncsfhi2)
3018 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
3019 #endif
3020 #ifdef HAVE_fix_truncsfsi2
3021 if (HAVE_fix_truncsfsi2)
3022 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
3023 #endif
3024 #ifdef HAVE_fix_truncsfdi2
3025 if (HAVE_fix_truncsfdi2)
3026 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
3027 #endif
3028
3029 #ifdef HAVE_fix_truncdfqi2
3030 if (HAVE_fix_truncdfqi2)
3031 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
3032 #endif
3033 #ifdef HAVE_fix_truncdfhi2
3034 if (HAVE_fix_truncdfhi2)
3035 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
3036 #endif
3037 #ifdef HAVE_fix_truncdfsi2
3038 if (HAVE_fix_truncdfsi2)
3039 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
3040 #endif
3041 #ifdef HAVE_fix_truncdfdi2
3042 if (HAVE_fix_truncdfdi2)
3043 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
3044 #endif
3045 #ifdef HAVE_fix_truncdfti2
3046 if (HAVE_fix_truncdfti2)
3047 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
3048 #endif
3049
3050 #ifdef HAVE_fix_truncxfqi2
3051 if (HAVE_fix_truncxfqi2)
3052 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
3053 #endif
3054 #ifdef HAVE_fix_truncxfhi2
3055 if (HAVE_fix_truncxfhi2)
3056 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
3057 #endif
3058 #ifdef HAVE_fix_truncxfsi2
3059 if (HAVE_fix_truncxfsi2)
3060 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
3061 #endif
3062 #ifdef HAVE_fix_truncxfdi2
3063 if (HAVE_fix_truncxfdi2)
3064 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
3065 #endif
3066 #ifdef HAVE_fix_truncxfti2
3067 if (HAVE_fix_truncxfti2)
3068 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
3069 #endif
3070
3071 #ifdef HAVE_fix_trunctfqi2
3072 if (HAVE_fix_trunctfqi2)
3073 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
3074 #endif
3075 #ifdef HAVE_fix_trunctfhi2
3076 if (HAVE_fix_trunctfhi2)
3077 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
3078 #endif
3079 #ifdef HAVE_fix_trunctfsi2
3080 if (HAVE_fix_trunctfsi2)
3081 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
3082 #endif
3083 #ifdef HAVE_fix_trunctfdi2
3084 if (HAVE_fix_trunctfdi2)
3085 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
3086 #endif
3087 #ifdef HAVE_fix_trunctfti2
3088 if (HAVE_fix_trunctfti2)
3089 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
3090 #endif
3091
3092 #ifdef HAVE_fixuns_truncqfqi2
3093 if (HAVE_fixuns_truncqfqi2)
3094 fixtrunctab[(int) QFmode][(int) QImode][1] = CODE_FOR_fixuns_truncqfqi2;
3095 #endif
3096 #ifdef HAVE_fixuns_trunchfqi2
3097 if (HAVE_fixuns_trunchfqi2)
3098 fixtrunctab[(int) HFmode][(int) QImode][1] = CODE_FOR_fixuns_trunchfqi2;
3099 #endif
3100 #ifdef HAVE_fixuns_trunchfhi2
3101 if (HAVE_fixuns_trunchfhi2)
3102 fixtrunctab[(int) HFmode][(int) HImode][1] = CODE_FOR_fixuns_trunchfhi2;
3103 #endif
3104 #ifdef HAVE_fixuns_truncsfqi2
3105 if (HAVE_fixuns_truncsfqi2)
3106 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
3107 #endif
3108 #ifdef HAVE_fixuns_truncsfhi2
3109 if (HAVE_fixuns_truncsfhi2)
3110 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
3111 #endif
3112 #ifdef HAVE_fixuns_truncsfsi2
3113 if (HAVE_fixuns_truncsfsi2)
3114 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
3115 #endif
3116 #ifdef HAVE_fixuns_truncsfdi2
3117 if (HAVE_fixuns_truncsfdi2)
3118 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
3119 #endif
3120
3121 #ifdef HAVE_fixuns_truncdfqi2
3122 if (HAVE_fixuns_truncdfqi2)
3123 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
3124 #endif
3125 #ifdef HAVE_fixuns_truncdfhi2
3126 if (HAVE_fixuns_truncdfhi2)
3127 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
3128 #endif
3129 #ifdef HAVE_fixuns_truncdfsi2
3130 if (HAVE_fixuns_truncdfsi2)
3131 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
3132 #endif
3133 #ifdef HAVE_fixuns_truncdfdi2
3134 if (HAVE_fixuns_truncdfdi2)
3135 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
3136 #endif
3137 #ifdef HAVE_fixuns_truncdfti2
3138 if (HAVE_fixuns_truncdfti2)
3139 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
3140 #endif
3141
3142 #ifdef HAVE_fixuns_truncxfqi2
3143 if (HAVE_fixuns_truncxfqi2)
3144 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
3145 #endif
3146 #ifdef HAVE_fixuns_truncxfhi2
3147 if (HAVE_fixuns_truncxfhi2)
3148 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
3149 #endif
3150 #ifdef HAVE_fixuns_truncxfsi2
3151 if (HAVE_fixuns_truncxfsi2)
3152 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
3153 #endif
3154 #ifdef HAVE_fixuns_truncxfdi2
3155 if (HAVE_fixuns_truncxfdi2)
3156 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
3157 #endif
3158 #ifdef HAVE_fixuns_truncxfti2
3159 if (HAVE_fixuns_truncxfti2)
3160 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
3161 #endif
3162
3163 #ifdef HAVE_fixuns_trunctfqi2
3164 if (HAVE_fixuns_trunctfqi2)
3165 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
3166 #endif
3167 #ifdef HAVE_fixuns_trunctfhi2
3168 if (HAVE_fixuns_trunctfhi2)
3169 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
3170 #endif
3171 #ifdef HAVE_fixuns_trunctfsi2
3172 if (HAVE_fixuns_trunctfsi2)
3173 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
3174 #endif
3175 #ifdef HAVE_fixuns_trunctfdi2
3176 if (HAVE_fixuns_trunctfdi2)
3177 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
3178 #endif
3179 #ifdef HAVE_fixuns_trunctfti2
3180 if (HAVE_fixuns_trunctfti2)
3181 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
3182 #endif
3183
3184 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3185 /* This flag says the same insns that convert to a signed fixnum
3186 also convert validly to an unsigned one. */
3187 {
3188 int i;
3189 int j;
3190 for (i = 0; i < NUM_MACHINE_MODES; i++)
3191 for (j = 0; j < NUM_MACHINE_MODES; j++)
3192 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3193 }
3194 #endif
3195 }
3196
3197 void
3198 init_floattab ()
3199 {
3200 enum insn_code *p;
3201 for (p = floattab[0][0];
3202 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3203 p++)
3204 *p = CODE_FOR_nothing;
3205
3206 #ifdef HAVE_floatqiqf2
3207 if (HAVE_floatqiqf2)
3208 floattab[(int) QFmode][(int) QImode][0] = CODE_FOR_floatqiqf2;
3209 #endif
3210 #ifdef HAVE_floathiqf2
3211 if (HAVE_floathiqf2)
3212 floattab[(int) QFmode][(int) HImode][0] = CODE_FOR_floathiqf2;
3213 #endif
3214 #ifdef HAVE_floatsiqf2
3215 if (HAVE_floatsiqf2)
3216 floattab[(int) QFmode][(int) SImode][0] = CODE_FOR_floatsiqf2;
3217 #endif
3218 #ifdef HAVE_floatdiqf2
3219 if (HAVE_floatdiqf2)
3220 floattab[(int) QFmode][(int) DImode][0] = CODE_FOR_floatdiqf2;
3221 #endif
3222 #ifdef HAVE_floattiqf2
3223 if (HAVE_floattiqf2)
3224 floattab[(int) QFmode][(int) TImode][0] = CODE_FOR_floattiqf2;
3225 #endif
3226
3227 #ifdef HAVE_floatqihf2
3228 if (HAVE_floatqihf2)
3229 floattab[(int) HFmode][(int) QImode][0] = CODE_FOR_floatqihf2;
3230 #endif
3231 #ifdef HAVE_floathihf2
3232 if (HAVE_floathihf2)
3233 floattab[(int) HFmode][(int) HImode][0] = CODE_FOR_floathihf2;
3234 #endif
3235 #ifdef HAVE_floatsihf2
3236 if (HAVE_floatsihf2)
3237 floattab[(int) HFmode][(int) SImode][0] = CODE_FOR_floatsihf2;
3238 #endif
3239 #ifdef HAVE_floatdihf2
3240 if (HAVE_floatdihf2)
3241 floattab[(int) HFmode][(int) DImode][0] = CODE_FOR_floatdihf2;
3242 #endif
3243 #ifdef HAVE_floattihf2
3244 if (HAVE_floattihf2)
3245 floattab[(int) HFmode][(int) TImode][0] = CODE_FOR_floattihf2;
3246 #endif
3247
3248 #ifdef HAVE_floatqisf2
3249 if (HAVE_floatqisf2)
3250 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
3251 #endif
3252 #ifdef HAVE_floathisf2
3253 if (HAVE_floathisf2)
3254 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
3255 #endif
3256 #ifdef HAVE_floatsisf2
3257 if (HAVE_floatsisf2)
3258 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
3259 #endif
3260 #ifdef HAVE_floatdisf2
3261 if (HAVE_floatdisf2)
3262 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
3263 #endif
3264 #ifdef HAVE_floattisf2
3265 if (HAVE_floattisf2)
3266 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
3267 #endif
3268
3269 #ifdef HAVE_floatqidf2
3270 if (HAVE_floatqidf2)
3271 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
3272 #endif
3273 #ifdef HAVE_floathidf2
3274 if (HAVE_floathidf2)
3275 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
3276 #endif
3277 #ifdef HAVE_floatsidf2
3278 if (HAVE_floatsidf2)
3279 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
3280 #endif
3281 #ifdef HAVE_floatdidf2
3282 if (HAVE_floatdidf2)
3283 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
3284 #endif
3285 #ifdef HAVE_floattidf2
3286 if (HAVE_floattidf2)
3287 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
3288 #endif
3289
3290 #ifdef HAVE_floatqixf2
3291 if (HAVE_floatqixf2)
3292 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
3293 #endif
3294 #ifdef HAVE_floathixf2
3295 if (HAVE_floathixf2)
3296 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
3297 #endif
3298 #ifdef HAVE_floatsixf2
3299 if (HAVE_floatsixf2)
3300 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
3301 #endif
3302 #ifdef HAVE_floatdixf2
3303 if (HAVE_floatdixf2)
3304 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
3305 #endif
3306 #ifdef HAVE_floattixf2
3307 if (HAVE_floattixf2)
3308 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
3309 #endif
3310
3311 #ifdef HAVE_floatqitf2
3312 if (HAVE_floatqitf2)
3313 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
3314 #endif
3315 #ifdef HAVE_floathitf2
3316 if (HAVE_floathitf2)
3317 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
3318 #endif
3319 #ifdef HAVE_floatsitf2
3320 if (HAVE_floatsitf2)
3321 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
3322 #endif
3323 #ifdef HAVE_floatditf2
3324 if (HAVE_floatditf2)
3325 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
3326 #endif
3327 #ifdef HAVE_floattitf2
3328 if (HAVE_floattitf2)
3329 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
3330 #endif
3331
3332 #ifdef HAVE_floatunsqiqf2
3333 if (HAVE_floatunsqiqf2)
3334 floattab[(int) QFmode][(int) QImode][1] = CODE_FOR_floatunsqiqf2;
3335 #endif
3336 #ifdef HAVE_floatunshiqf2
3337 if (HAVE_floatunshiqf2)
3338 floattab[(int) QFmode][(int) HImode][1] = CODE_FOR_floatunshiqf2;
3339 #endif
3340 #ifdef HAVE_floatunssiqf2
3341 if (HAVE_floatunsqsiqf2)
3342 floattab[(int) QFmode][(int) SImode][1] = CODE_FOR_floatunssiqf2;
3343 #endif
3344 #ifdef HAVE_floatunsdiqf2
3345 if (HAVE_floatunsdiqf2)
3346 floattab[(int) QFmode][(int) DImode][1] = CODE_FOR_floatunsdiqf2;
3347 #endif
3348 #ifdef HAVE_floatunstiqf2
3349 if (HAVE_floatunstiqf2)
3350 floattab[(int) QFmode][(int) TImode][1] = CODE_FOR_floatunstiqf2;
3351 #endif
3352
3353 #ifdef HAVE_floatunsqihf2
3354 if (HAVE_floatunsqihf2)
3355 floattab[(int) HFmode][(int) QImode][1] = CODE_FOR_floatunsqihf2;
3356 #endif
3357 #ifdef HAVE_floatunshihf2
3358 if (HAVE_floatunshihf2)
3359 floattab[(int) HFmode][(int) HImode][1] = CODE_FOR_floatunshihf2;
3360 #endif
3361 #ifdef HAVE_floatunssihf2
3362 if (HAVE_floatunssihf2)
3363 floattab[(int) HFmode][(int) SImode][1] = CODE_FOR_floatunssihf2;
3364 #endif
3365 #ifdef HAVE_floatunsdihf2
3366 if (HAVE_floatunsdihf2)
3367 floattab[(int) HFmode][(int) DImode][1] = CODE_FOR_floatunsdihf2;
3368 #endif
3369 #ifdef HAVE_floatunstihf2
3370 if (HAVE_floatunstihf2)
3371 floattab[(int) HFmode][(int) TImode][1] = CODE_FOR_floatunstihf2;
3372 #endif
3373
3374 #ifdef HAVE_floatqunsqisf2
3375 if (HAVE_floatunsqisf2)
3376 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
3377 #endif
3378 #ifdef HAVE_floatunshisf2
3379 if (HAVE_floatunshisf2)
3380 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
3381 #endif
3382 #ifdef HAVE_floatunssisf2
3383 if (HAVE_floatunssisf2)
3384 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
3385 #endif
3386 #ifdef HAVE_floatunsdisf2
3387 if (HAVE_floatunsdisf2)
3388 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
3389 #endif
3390 #ifdef HAVE_floatunstisf2
3391 if (HAVE_floatunstisf2)
3392 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
3393 #endif
3394
3395 #ifdef HAVE_floatunsqidf2
3396 if (HAVE_floatunsqidf2)
3397 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
3398 #endif
3399 #ifdef HAVE_floatunshidf2
3400 if (HAVE_floatunshidf2)
3401 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
3402 #endif
3403 #ifdef HAVE_floatunssidf2
3404 if (HAVE_floatunssidf2)
3405 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
3406 #endif
3407 #ifdef HAVE_floatunsdidf2
3408 if (HAVE_floatunsdidf2)
3409 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
3410 #endif
3411 #ifdef HAVE_floatunstidf2
3412 if (HAVE_floatunstidf2)
3413 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
3414 #endif
3415
3416 #ifdef HAVE_floatunsqixf2
3417 if (HAVE_floatunsqixf2)
3418 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
3419 #endif
3420 #ifdef HAVE_floatunshixf2
3421 if (HAVE_floatunshixf2)
3422 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
3423 #endif
3424 #ifdef HAVE_floatunssixf2
3425 if (HAVE_floatunssixf2)
3426 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
3427 #endif
3428 #ifdef HAVE_floatunsdixf2
3429 if (HAVE_floatunsdixf2)
3430 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
3431 #endif
3432 #ifdef HAVE_floatunstixf2
3433 if (HAVE_floatunstixf2)
3434 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
3435 #endif
3436
3437 #ifdef HAVE_floatunsqitf2
3438 if (HAVE_floatunsqitf2)
3439 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
3440 #endif
3441 #ifdef HAVE_floatunshitf2
3442 if (HAVE_floatunshitf2)
3443 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
3444 #endif
3445 #ifdef HAVE_floatunssitf2
3446 if (HAVE_floatunssitf2)
3447 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
3448 #endif
3449 #ifdef HAVE_floatunsditf2
3450 if (HAVE_floatunsditf2)
3451 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
3452 #endif
3453 #ifdef HAVE_floatunstitf2
3454 if (HAVE_floatunstitf2)
3455 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
3456 #endif
3457 }
3458 \f
3459 /* Generate code to convert FROM to floating point
3460 and store in TO. FROM must be fixed point and not VOIDmode.
3461 UNSIGNEDP nonzero means regard FROM as unsigned.
3462 Normally this is done by correcting the final value
3463 if it is negative. */
3464
3465 void
3466 expand_float (to, from, unsignedp)
3467 rtx to, from;
3468 int unsignedp;
3469 {
3470 enum insn_code icode;
3471 register rtx target = to;
3472 enum machine_mode fmode, imode;
3473
3474 /* Crash now, because we won't be able to decide which mode to use. */
3475 if (GET_MODE (from) == VOIDmode)
3476 abort ();
3477
3478 /* Look for an insn to do the conversion. Do it in the specified
3479 modes if possible; otherwise convert either input, output or both to
3480 wider mode. If the integer mode is wider than the mode of FROM,
3481 we can do the conversion signed even if the input is unsigned. */
3482
3483 for (imode = GET_MODE (from); imode != VOIDmode;
3484 imode = GET_MODE_WIDER_MODE (imode))
3485 for (fmode = GET_MODE (to); fmode != VOIDmode;
3486 fmode = GET_MODE_WIDER_MODE (fmode))
3487 {
3488 int doing_unsigned = unsignedp;
3489
3490 icode = can_float_p (fmode, imode, unsignedp);
3491 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3492 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3493
3494 if (icode != CODE_FOR_nothing)
3495 {
3496 to = protect_from_queue (to, 1);
3497 from = protect_from_queue (from, 0);
3498
3499 if (imode != GET_MODE (from))
3500 from = convert_to_mode (imode, from, unsignedp);
3501
3502 if (fmode != GET_MODE (to))
3503 target = gen_reg_rtx (fmode);
3504
3505 emit_unop_insn (icode, target, from,
3506 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3507
3508 if (target != to)
3509 convert_move (to, target, 0);
3510 return;
3511 }
3512 }
3513
3514 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3515
3516 /* Unsigned integer, and no way to convert directly.
3517 Convert as signed, then conditionally adjust the result. */
3518 if (unsignedp)
3519 {
3520 rtx label = gen_label_rtx ();
3521 rtx temp;
3522 REAL_VALUE_TYPE offset;
3523
3524 emit_queue ();
3525
3526 to = protect_from_queue (to, 1);
3527 from = protect_from_queue (from, 0);
3528
3529 if (flag_force_mem)
3530 from = force_not_mem (from);
3531
3532 /* If we are about to do some arithmetic to correct for an
3533 unsigned operand, do it in a pseudo-register. */
3534
3535 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3536 target = gen_reg_rtx (GET_MODE (to));
3537
3538 /* Convert as signed integer to floating. */
3539 expand_float (target, from, 0);
3540
3541 /* If FROM is negative (and therefore TO is negative),
3542 correct its value by 2**bitwidth. */
3543
3544 do_pending_stack_adjust ();
3545 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3546 emit_jump_insn (gen_bge (label));
3547 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3548 Rather than setting up a dconst_dot_5, let's hope SCO
3549 fixes the bug. */
3550 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3551 temp = expand_binop (GET_MODE (to), add_optab, target,
3552 immed_real_const_1 (offset, GET_MODE (to)),
3553 target, 0, OPTAB_LIB_WIDEN);
3554 if (temp != target)
3555 emit_move_insn (target, temp);
3556 do_pending_stack_adjust ();
3557 emit_label (label);
3558 }
3559 else
3560 #endif
3561
3562 /* No hardware instruction available; call a library rotine to convert from
3563 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3564 {
3565 rtx libfcn;
3566 rtx insns;
3567
3568 to = protect_from_queue (to, 1);
3569 from = protect_from_queue (from, 0);
3570
3571 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3572 from = convert_to_mode (SImode, from, unsignedp);
3573
3574 if (flag_force_mem)
3575 from = force_not_mem (from);
3576
3577 if (GET_MODE (to) == SFmode)
3578 {
3579 if (GET_MODE (from) == SImode)
3580 libfcn = floatsisf_libfunc;
3581 else if (GET_MODE (from) == DImode)
3582 libfcn = floatdisf_libfunc;
3583 else if (GET_MODE (from) == TImode)
3584 libfcn = floattisf_libfunc;
3585 else
3586 abort ();
3587 }
3588 else if (GET_MODE (to) == DFmode)
3589 {
3590 if (GET_MODE (from) == SImode)
3591 libfcn = floatsidf_libfunc;
3592 else if (GET_MODE (from) == DImode)
3593 libfcn = floatdidf_libfunc;
3594 else if (GET_MODE (from) == TImode)
3595 libfcn = floattidf_libfunc;
3596 else
3597 abort ();
3598 }
3599 else if (GET_MODE (to) == XFmode)
3600 {
3601 if (GET_MODE (from) == SImode)
3602 libfcn = floatsixf_libfunc;
3603 else if (GET_MODE (from) == DImode)
3604 libfcn = floatdixf_libfunc;
3605 else if (GET_MODE (from) == TImode)
3606 libfcn = floattixf_libfunc;
3607 else
3608 abort ();
3609 }
3610 else if (GET_MODE (to) == TFmode)
3611 {
3612 if (GET_MODE (from) == SImode)
3613 libfcn = floatsitf_libfunc;
3614 else if (GET_MODE (from) == DImode)
3615 libfcn = floatditf_libfunc;
3616 else if (GET_MODE (from) == TImode)
3617 libfcn = floattitf_libfunc;
3618 else
3619 abort ();
3620 }
3621 else
3622 abort ();
3623
3624 start_sequence ();
3625
3626 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3627 insns = get_insns ();
3628 end_sequence ();
3629
3630 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3631 gen_rtx (FLOAT, GET_MODE (to), from));
3632 }
3633
3634 /* Copy result to requested destination
3635 if we have been computing in a temp location. */
3636
3637 if (target != to)
3638 {
3639 if (GET_MODE (target) == GET_MODE (to))
3640 emit_move_insn (to, target);
3641 else
3642 convert_move (to, target, 0);
3643 }
3644 }
3645 \f
3646 /* expand_fix: generate code to convert FROM to fixed point
3647 and store in TO. FROM must be floating point. */
3648
3649 static rtx
3650 ftruncify (x)
3651 rtx x;
3652 {
3653 rtx temp = gen_reg_rtx (GET_MODE (x));
3654 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3655 }
3656
3657 void
3658 expand_fix (to, from, unsignedp)
3659 register rtx to, from;
3660 int unsignedp;
3661 {
3662 enum insn_code icode;
3663 register rtx target = to;
3664 enum machine_mode fmode, imode;
3665 int must_trunc = 0;
3666 rtx libfcn = 0;
3667
3668 /* We first try to find a pair of modes, one real and one integer, at
3669 least as wide as FROM and TO, respectively, in which we can open-code
3670 this conversion. If the integer mode is wider than the mode of TO,
3671 we can do the conversion either signed or unsigned. */
3672
3673 for (imode = GET_MODE (to); imode != VOIDmode;
3674 imode = GET_MODE_WIDER_MODE (imode))
3675 for (fmode = GET_MODE (from); fmode != VOIDmode;
3676 fmode = GET_MODE_WIDER_MODE (fmode))
3677 {
3678 int doing_unsigned = unsignedp;
3679
3680 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3681 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3682 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3683
3684 if (icode != CODE_FOR_nothing)
3685 {
3686 to = protect_from_queue (to, 1);
3687 from = protect_from_queue (from, 0);
3688
3689 if (fmode != GET_MODE (from))
3690 from = convert_to_mode (fmode, from, 0);
3691
3692 if (must_trunc)
3693 from = ftruncify (from);
3694
3695 if (imode != GET_MODE (to))
3696 target = gen_reg_rtx (imode);
3697
3698 emit_unop_insn (icode, target, from,
3699 doing_unsigned ? UNSIGNED_FIX : FIX);
3700 if (target != to)
3701 convert_move (to, target, unsignedp);
3702 return;
3703 }
3704 }
3705
3706 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3707 /* For an unsigned conversion, there is one more way to do it.
3708 If we have a signed conversion, we generate code that compares
3709 the real value to the largest representable positive number. If if
3710 is smaller, the conversion is done normally. Otherwise, subtract
3711 one plus the highest signed number, convert, and add it back.
3712
3713 We only need to check all real modes, since we know we didn't find
3714 anything with a wider integer mode. */
3715
3716 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3717 for (fmode = GET_MODE (from); fmode != VOIDmode;
3718 fmode = GET_MODE_WIDER_MODE (fmode))
3719 /* Make sure we won't lose significant bits doing this. */
3720 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3721 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3722 &must_trunc))
3723 {
3724 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3725 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3726 rtx limit = immed_real_const_1 (offset, fmode);
3727 rtx lab1 = gen_label_rtx ();
3728 rtx lab2 = gen_label_rtx ();
3729 rtx insn;
3730
3731 emit_queue ();
3732 to = protect_from_queue (to, 1);
3733 from = protect_from_queue (from, 0);
3734
3735 if (flag_force_mem)
3736 from = force_not_mem (from);
3737
3738 if (fmode != GET_MODE (from))
3739 from = convert_to_mode (fmode, from, 0);
3740
3741 /* See if we need to do the subtraction. */
3742 do_pending_stack_adjust ();
3743 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3744 emit_jump_insn (gen_bge (lab1));
3745
3746 /* If not, do the signed "fix" and branch around fixup code. */
3747 expand_fix (to, from, 0);
3748 emit_jump_insn (gen_jump (lab2));
3749 emit_barrier ();
3750
3751 /* Otherwise, subtract 2**(N-1), convert to signed number,
3752 then add 2**(N-1). Do the addition using XOR since this
3753 will often generate better code. */
3754 emit_label (lab1);
3755 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3756 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3757 expand_fix (to, target, 0);
3758 target = expand_binop (GET_MODE (to), xor_optab, to,
3759 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3760 to, 1, OPTAB_LIB_WIDEN);
3761
3762 if (target != to)
3763 emit_move_insn (to, target);
3764
3765 emit_label (lab2);
3766
3767 /* Make a place for a REG_NOTE and add it. */
3768 insn = emit_move_insn (to, to);
3769 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3770 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3771 from), REG_NOTES (insn));
3772
3773 return;
3774 }
3775 #endif
3776
3777 /* We can't do it with an insn, so use a library call. But first ensure
3778 that the mode of TO is at least as wide as SImode, since those are the
3779 only library calls we know about. */
3780
3781 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3782 {
3783 target = gen_reg_rtx (SImode);
3784
3785 expand_fix (target, from, unsignedp);
3786 }
3787 else if (GET_MODE (from) == SFmode)
3788 {
3789 if (GET_MODE (to) == SImode)
3790 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3791 else if (GET_MODE (to) == DImode)
3792 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3793 else if (GET_MODE (to) == TImode)
3794 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3795 else
3796 abort ();
3797 }
3798 else if (GET_MODE (from) == DFmode)
3799 {
3800 if (GET_MODE (to) == SImode)
3801 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3802 else if (GET_MODE (to) == DImode)
3803 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3804 else if (GET_MODE (to) == TImode)
3805 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3806 else
3807 abort ();
3808 }
3809 else if (GET_MODE (from) == XFmode)
3810 {
3811 if (GET_MODE (to) == SImode)
3812 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3813 else if (GET_MODE (to) == DImode)
3814 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3815 else if (GET_MODE (to) == TImode)
3816 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3817 else
3818 abort ();
3819 }
3820 else if (GET_MODE (from) == TFmode)
3821 {
3822 if (GET_MODE (to) == SImode)
3823 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3824 else if (GET_MODE (to) == DImode)
3825 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3826 else if (GET_MODE (to) == TImode)
3827 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3828 else
3829 abort ();
3830 }
3831 else
3832 abort ();
3833
3834 if (libfcn)
3835 {
3836 rtx insns;
3837
3838 to = protect_from_queue (to, 1);
3839 from = protect_from_queue (from, 0);
3840
3841 if (flag_force_mem)
3842 from = force_not_mem (from);
3843
3844 start_sequence ();
3845
3846 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3847 insns = get_insns ();
3848 end_sequence ();
3849
3850 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3851 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3852 GET_MODE (to), from));
3853 }
3854
3855 if (GET_MODE (to) == GET_MODE (target))
3856 emit_move_insn (to, target);
3857 else
3858 convert_move (to, target, 0);
3859 }
3860 \f
3861 static optab
3862 init_optab (code)
3863 enum rtx_code code;
3864 {
3865 int i;
3866 optab op = (optab) xmalloc (sizeof (struct optab));
3867 op->code = code;
3868 for (i = 0; i < NUM_MACHINE_MODES; i++)
3869 {
3870 op->handlers[i].insn_code = CODE_FOR_nothing;
3871 op->handlers[i].libfunc = 0;
3872 }
3873 return op;
3874 }
3875
3876 /* Initialize the libfunc fields of an entire group of entries in some
3877 optab. Each entry is set equal to a string consisting of a leading
3878 pair of underscores followed by a generic operation name followed by
3879 a mode name (downshifted to lower case) followed by a single character
3880 representing the number of operands for the given operation (which is
3881 usually one of the characters '2', '3', or '4').
3882
3883 OPTABLE is the table in which libfunc fields are to be initialized.
3884 FIRST_MODE is the first machine mode index in the given optab to
3885 initialize.
3886 LAST_MODE is the last machine mode index in the given optab to
3887 initialize.
3888 OPNAME is the generic (string) name of the operation.
3889 SUFFIX is the character which specifies the number of operands for
3890 the given generic operation.
3891 */
3892
3893 static void
3894 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3895 register optab optable;
3896 register char *opname;
3897 register int first_mode;
3898 register int last_mode;
3899 register char suffix;
3900 {
3901 register int mode;
3902 register unsigned opname_len = strlen (opname);
3903
3904 for (mode = first_mode; (int) mode <= (int) last_mode;
3905 mode = (enum machine_mode) ((int) mode + 1))
3906 {
3907 register char *mname = mode_name[(int) mode];
3908 register unsigned mname_len = strlen (mname);
3909 register char *libfunc_name
3910 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3911 register char *p;
3912 register char *q;
3913
3914 p = libfunc_name;
3915 *p++ = '_';
3916 *p++ = '_';
3917 for (q = opname; *q; )
3918 *p++ = *q++;
3919 for (q = mname; *q; q++)
3920 *p++ = tolower (*q);
3921 *p++ = suffix;
3922 *p++ = '\0';
3923 optable->handlers[(int) mode].libfunc
3924 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3925 }
3926 }
3927
3928 /* Initialize the libfunc fields of an entire group of entries in some
3929 optab which correspond to all integer mode operations. The parameters
3930 have the same meaning as similarly named ones for the `init_libfuncs'
3931 routine. (See above). */
3932
3933 static void
3934 init_integral_libfuncs (optable, opname, suffix)
3935 register optab optable;
3936 register char *opname;
3937 register char suffix;
3938 {
3939 init_libfuncs (optable, SImode, TImode, opname, suffix);
3940 }
3941
3942 /* Initialize the libfunc fields of an entire group of entries in some
3943 optab which correspond to all real mode operations. The parameters
3944 have the same meaning as similarly named ones for the `init_libfuncs'
3945 routine. (See above). */
3946
3947 static void
3948 init_floating_libfuncs (optable, opname, suffix)
3949 register optab optable;
3950 register char *opname;
3951 register char suffix;
3952 {
3953 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3954 }
3955
3956 /* Initialize the libfunc fields of an entire group of entries in some
3957 optab which correspond to all complex floating modes. The parameters
3958 have the same meaning as similarly named ones for the `init_libfuncs'
3959 routine. (See above). */
3960
3961 static void
3962 init_complex_libfuncs (optable, opname, suffix)
3963 register optab optable;
3964 register char *opname;
3965 register char suffix;
3966 {
3967 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3968 }
3969
3970 /* Call this once to initialize the contents of the optabs
3971 appropriately for the current target machine. */
3972
3973 void
3974 init_optabs ()
3975 {
3976 int i;
3977
3978 init_fixtab ();
3979 init_floattab ();
3980 init_extends ();
3981
3982 add_optab = init_optab (PLUS);
3983 sub_optab = init_optab (MINUS);
3984 smul_optab = init_optab (MULT);
3985 smul_widen_optab = init_optab (UNKNOWN);
3986 umul_widen_optab = init_optab (UNKNOWN);
3987 sdiv_optab = init_optab (DIV);
3988 sdivmod_optab = init_optab (UNKNOWN);
3989 udiv_optab = init_optab (UDIV);
3990 udivmod_optab = init_optab (UNKNOWN);
3991 smod_optab = init_optab (MOD);
3992 umod_optab = init_optab (UMOD);
3993 flodiv_optab = init_optab (DIV);
3994 ftrunc_optab = init_optab (UNKNOWN);
3995 and_optab = init_optab (AND);
3996 ior_optab = init_optab (IOR);
3997 xor_optab = init_optab (XOR);
3998 ashl_optab = init_optab (ASHIFT);
3999 ashr_optab = init_optab (ASHIFTRT);
4000 lshl_optab = init_optab (LSHIFT);
4001 lshr_optab = init_optab (LSHIFTRT);
4002 rotl_optab = init_optab (ROTATE);
4003 rotr_optab = init_optab (ROTATERT);
4004 smin_optab = init_optab (SMIN);
4005 smax_optab = init_optab (SMAX);
4006 umin_optab = init_optab (UMIN);
4007 umax_optab = init_optab (UMAX);
4008 mov_optab = init_optab (UNKNOWN);
4009 movstrict_optab = init_optab (UNKNOWN);
4010 cmp_optab = init_optab (UNKNOWN);
4011 ucmp_optab = init_optab (UNKNOWN);
4012 tst_optab = init_optab (UNKNOWN);
4013 neg_optab = init_optab (NEG);
4014 abs_optab = init_optab (ABS);
4015 one_cmpl_optab = init_optab (NOT);
4016 ffs_optab = init_optab (FFS);
4017 sqrt_optab = init_optab (SQRT);
4018 sin_optab = init_optab (UNKNOWN);
4019 cos_optab = init_optab (UNKNOWN);
4020 strlen_optab = init_optab (UNKNOWN);
4021
4022 #ifdef HAVE_addqi3
4023 if (HAVE_addqi3)
4024 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
4025 #endif
4026 #ifdef HAVE_addhi3
4027 if (HAVE_addhi3)
4028 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
4029 #endif
4030 #ifdef HAVE_addpsi3
4031 if (HAVE_addpsi3)
4032 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
4033 #endif
4034 #ifdef HAVE_addsi3
4035 if (HAVE_addsi3)
4036 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
4037 #endif
4038 #ifdef HAVE_adddi3
4039 if (HAVE_adddi3)
4040 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
4041 #endif
4042 #ifdef HAVE_addti3
4043 if (HAVE_addti3)
4044 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
4045 #endif
4046 #ifdef HAVE_addqf3
4047 if (HAVE_addqf3)
4048 add_optab->handlers[(int) QFmode].insn_code = CODE_FOR_addqf3;
4049 #endif
4050 #ifdef HAVE_addhf3
4051 if (HAVE_addhf3)
4052 add_optab->handlers[(int) HFmode].insn_code = CODE_FOR_addhf3;
4053 #endif
4054 #ifdef HAVE_addsf3
4055 if (HAVE_addsf3)
4056 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
4057 #endif
4058 #ifdef HAVE_adddf3
4059 if (HAVE_adddf3)
4060 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
4061 #endif
4062 #ifdef HAVE_addxf3
4063 if (HAVE_addxf3)
4064 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
4065 #endif
4066 #ifdef HAVE_addtf3
4067 if (HAVE_addtf3)
4068 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
4069 #endif
4070 init_integral_libfuncs (add_optab, "add", '3');
4071 init_floating_libfuncs (add_optab, "add", '3');
4072
4073 #ifdef HAVE_subqi3
4074 if (HAVE_subqi3)
4075 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
4076 #endif
4077 #ifdef HAVE_subhi3
4078 if (HAVE_subhi3)
4079 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
4080 #endif
4081 #ifdef HAVE_subpsi3
4082 if (HAVE_subpsi3)
4083 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
4084 #endif
4085 #ifdef HAVE_subsi3
4086 if (HAVE_subsi3)
4087 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
4088 #endif
4089 #ifdef HAVE_subdi3
4090 if (HAVE_subdi3)
4091 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
4092 #endif
4093 #ifdef HAVE_subti3
4094 if (HAVE_subti3)
4095 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
4096 #endif
4097 #ifdef HAVE_subqf3
4098 if (HAVE_subqf3)
4099 sub_optab->handlers[(int) QFmode].insn_code = CODE_FOR_subqf3;
4100 #endif
4101 #ifdef HAVE_subhf3
4102 if (HAVE_subhf3)
4103 sub_optab->handlers[(int) HFmode].insn_code = CODE_FOR_subhf3;
4104 #endif
4105 #ifdef HAVE_subsf3
4106 if (HAVE_subsf3)
4107 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
4108 #endif
4109 #ifdef HAVE_subdf3
4110 if (HAVE_subdf3)
4111 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
4112 #endif
4113 #ifdef HAVE_subxf3
4114 if (HAVE_subxf3)
4115 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
4116 #endif
4117 #ifdef HAVE_subtf3
4118 if (HAVE_subtf3)
4119 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
4120 #endif
4121 init_integral_libfuncs (sub_optab, "sub", '3');
4122 init_floating_libfuncs (sub_optab, "sub", '3');
4123
4124 #ifdef HAVE_mulqi3
4125 if (HAVE_mulqi3)
4126 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
4127 #endif
4128 #ifdef HAVE_mulhi3
4129 if (HAVE_mulhi3)
4130 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
4131 #endif
4132 #ifdef HAVE_mulpsi3
4133 if (HAVE_mulpsi3)
4134 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
4135 #endif
4136 #ifdef HAVE_mulsi3
4137 if (HAVE_mulsi3)
4138 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
4139 #endif
4140 #ifdef HAVE_muldi3
4141 if (HAVE_muldi3)
4142 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
4143 #endif
4144 #ifdef HAVE_multi3
4145 if (HAVE_multi3)
4146 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
4147 #endif
4148 #ifdef HAVE_mulqf3
4149 if (HAVE_mulqf3)
4150 smul_optab->handlers[(int) QFmode].insn_code = CODE_FOR_mulqf3;
4151 #endif
4152 #ifdef HAVE_mulhf3
4153 if (HAVE_mulhf3)
4154 smul_optab->handlers[(int) HFmode].insn_code = CODE_FOR_mulhf3;
4155 #endif
4156 #ifdef HAVE_mulsf3
4157 if (HAVE_mulsf3)
4158 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
4159 #endif
4160 #ifdef HAVE_muldf3
4161 if (HAVE_muldf3)
4162 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
4163 #endif
4164 #ifdef HAVE_mulxf3
4165 if (HAVE_mulxf3)
4166 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
4167 #endif
4168 #ifdef HAVE_multf3
4169 if (HAVE_multf3)
4170 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
4171 #endif
4172 init_integral_libfuncs (smul_optab, "mul", '3');
4173 init_floating_libfuncs (smul_optab, "mul", '3');
4174
4175 #ifdef MULSI3_LIBCALL
4176 smul_optab->handlers[(int) SImode].libfunc
4177 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4178 #endif
4179 #ifdef MULDI3_LIBCALL
4180 smul_optab->handlers[(int) DImode].libfunc
4181 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4182 #endif
4183 #ifdef MULTI3_LIBCALL
4184 smul_optab->handlers[(int) TImode].libfunc
4185 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
4186 #endif
4187
4188 #ifdef HAVE_mulqihi3
4189 if (HAVE_mulqihi3)
4190 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
4191 #endif
4192 #ifdef HAVE_mulhisi3
4193 if (HAVE_mulhisi3)
4194 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
4195 #endif
4196 #ifdef HAVE_mulsidi3
4197 if (HAVE_mulsidi3)
4198 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
4199 #endif
4200 #ifdef HAVE_mulditi3
4201 if (HAVE_mulditi3)
4202 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
4203 #endif
4204
4205 #ifdef HAVE_umulqihi3
4206 if (HAVE_umulqihi3)
4207 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
4208 #endif
4209 #ifdef HAVE_umulhisi3
4210 if (HAVE_umulhisi3)
4211 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
4212 #endif
4213 #ifdef HAVE_umulsidi3
4214 if (HAVE_umulsidi3)
4215 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
4216 #endif
4217 #ifdef HAVE_umulditi3
4218 if (HAVE_umulditi3)
4219 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
4220 #endif
4221
4222 #ifdef HAVE_divqi3
4223 if (HAVE_divqi3)
4224 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
4225 #endif
4226 #ifdef HAVE_divhi3
4227 if (HAVE_divhi3)
4228 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
4229 #endif
4230 #ifdef HAVE_divpsi3
4231 if (HAVE_divpsi3)
4232 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
4233 #endif
4234 #ifdef HAVE_divsi3
4235 if (HAVE_divsi3)
4236 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
4237 #endif
4238 #ifdef HAVE_divdi3
4239 if (HAVE_divdi3)
4240 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
4241 #endif
4242 #ifdef HAVE_divti3
4243 if (HAVE_divti3)
4244 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
4245 #endif
4246 init_integral_libfuncs (sdiv_optab, "div", '3');
4247
4248 #ifdef DIVSI3_LIBCALL
4249 sdiv_optab->handlers[(int) SImode].libfunc
4250 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4251 #endif
4252 #ifdef DIVDI3_LIBCALL
4253 sdiv_optab->handlers[(int) DImode].libfunc
4254 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4255 #endif
4256 #ifdef DIVTI3_LIBCALL
4257 sdiv_optab->handlers[(int) TImode].libfunc
4258 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
4259 #endif
4260
4261 #ifdef HAVE_udivqi3
4262 if (HAVE_udivqi3)
4263 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
4264 #endif
4265 #ifdef HAVE_udivhi3
4266 if (HAVE_udivhi3)
4267 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
4268 #endif
4269 #ifdef HAVE_udivpsi3
4270 if (HAVE_udivpsi3)
4271 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
4272 #endif
4273 #ifdef HAVE_udivsi3
4274 if (HAVE_udivsi3)
4275 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
4276 #endif
4277 #ifdef HAVE_udivdi3
4278 if (HAVE_udivdi3)
4279 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
4280 #endif
4281 #ifdef HAVE_udivti3
4282 if (HAVE_udivti3)
4283 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
4284 #endif
4285 init_integral_libfuncs (udiv_optab, "udiv", '3');
4286
4287 #ifdef UDIVSI3_LIBCALL
4288 udiv_optab->handlers[(int) SImode].libfunc
4289 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4290 #endif
4291 #ifdef UDIVDI3_LIBCALL
4292 udiv_optab->handlers[(int) DImode].libfunc
4293 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4294 #endif
4295 #ifdef UDIVTI3_LIBCALL
4296 udiv_optab->handlers[(int) TImode].libfunc
4297 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
4298 #endif
4299
4300 #ifdef HAVE_divmodqi4
4301 if (HAVE_divmodqi4)
4302 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
4303 #endif
4304 #ifdef HAVE_divmodhi4
4305 if (HAVE_divmodhi4)
4306 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
4307 #endif
4308 #ifdef HAVE_divmodsi4
4309 if (HAVE_divmodsi4)
4310 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
4311 #endif
4312 #ifdef HAVE_divmoddi4
4313 if (HAVE_divmoddi4)
4314 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
4315 #endif
4316 #ifdef HAVE_divmodti4
4317 if (HAVE_divmodti4)
4318 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
4319 #endif
4320 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4321
4322 #ifdef HAVE_udivmodqi4
4323 if (HAVE_udivmodqi4)
4324 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
4325 #endif
4326 #ifdef HAVE_udivmodhi4
4327 if (HAVE_udivmodhi4)
4328 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
4329 #endif
4330 #ifdef HAVE_udivmodsi4
4331 if (HAVE_udivmodsi4)
4332 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
4333 #endif
4334 #ifdef HAVE_udivmoddi4
4335 if (HAVE_udivmoddi4)
4336 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
4337 #endif
4338 #ifdef HAVE_udivmodti4
4339 if (HAVE_udivmodti4)
4340 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
4341 #endif
4342 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4343
4344 #ifdef HAVE_modqi3
4345 if (HAVE_modqi3)
4346 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
4347 #endif
4348 #ifdef HAVE_modhi3
4349 if (HAVE_modhi3)
4350 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
4351 #endif
4352 #ifdef HAVE_modpsi3
4353 if (HAVE_modpsi3)
4354 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
4355 #endif
4356 #ifdef HAVE_modsi3
4357 if (HAVE_modsi3)
4358 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
4359 #endif
4360 #ifdef HAVE_moddi3
4361 if (HAVE_moddi3)
4362 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
4363 #endif
4364 #ifdef HAVE_modti3
4365 if (HAVE_modti3)
4366 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
4367 #endif
4368 init_integral_libfuncs (smod_optab, "mod", '3');
4369
4370 #ifdef MODSI3_LIBCALL
4371 smod_optab->handlers[(int) SImode].libfunc
4372 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4373 #endif
4374 #ifdef MODDI3_LIBCALL
4375 smod_optab->handlers[(int) DImode].libfunc
4376 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4377 #endif
4378 #ifdef MODTI3_LIBCALL
4379 smod_optab->handlers[(int) TImode].libfunc
4380 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
4381 #endif
4382
4383 #ifdef HAVE_umodqi3
4384 if (HAVE_umodqi3)
4385 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
4386 #endif
4387 #ifdef HAVE_umodhi3
4388 if (HAVE_umodhi3)
4389 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
4390 #endif
4391 #ifdef HAVE_umodpsi3
4392 if (HAVE_umodpsi3)
4393 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
4394 #endif
4395 #ifdef HAVE_umodsi3
4396 if (HAVE_umodsi3)
4397 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
4398 #endif
4399 #ifdef HAVE_umoddi3
4400 if (HAVE_umoddi3)
4401 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
4402 #endif
4403 #ifdef HAVE_umodti3
4404 if (HAVE_umodti3)
4405 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
4406 #endif
4407 init_integral_libfuncs (umod_optab, "umod", '3');
4408
4409 #ifdef UMODSI3_LIBCALL
4410 umod_optab->handlers[(int) SImode].libfunc
4411 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4412 #endif
4413 #ifdef UMODDI3_LIBCALL
4414 umod_optab->handlers[(int) DImode].libfunc
4415 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4416 #endif
4417 #ifdef UMODTI3_LIBCALL
4418 umod_optab->handlers[(int) TImode].libfunc
4419 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4420 #endif
4421
4422 #ifdef HAVE_divqf3
4423 if (HAVE_divqf3)
4424 flodiv_optab->handlers[(int) QFmode].insn_code = CODE_FOR_divqf3;
4425 #endif
4426 #ifdef HAVE_divhf3
4427 if (HAVE_divhf3)
4428 flodiv_optab->handlers[(int) HFmode].insn_code = CODE_FOR_divhf3;
4429 #endif
4430 #ifdef HAVE_divsf3
4431 if (HAVE_divsf3)
4432 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
4433 #endif
4434 #ifdef HAVE_divdf3
4435 if (HAVE_divdf3)
4436 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
4437 #endif
4438 #ifdef HAVE_divxf3
4439 if (HAVE_divxf3)
4440 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
4441 #endif
4442 #ifdef HAVE_divtf3
4443 if (HAVE_divtf3)
4444 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
4445 #endif
4446 init_floating_libfuncs (flodiv_optab, "div", '3');
4447
4448 #ifdef HAVE_ftruncqf2
4449 if (HAVE_ftruncqf2)
4450 ftrunc_optab->handlers[(int) QFmode].insn_code = CODE_FOR_ftruncqf2;
4451 #endif
4452 #ifdef HAVE_ftrunchf2
4453 if (HAVE_ftrunchf2)
4454 ftrunc_optab->handlers[(int) HFmode].insn_code = CODE_FOR_ftrunchf3;
4455 #endif
4456 #ifdef HAVE_ftruncsf2
4457 if (HAVE_ftruncsf2)
4458 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
4459 #endif
4460 #ifdef HAVE_ftruncdf2
4461 if (HAVE_ftruncdf2)
4462 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
4463 #endif
4464 #ifdef HAVE_ftruncxf2
4465 if (HAVE_ftruncxf2)
4466 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
4467 #endif
4468 #ifdef HAVE_ftrunctf2
4469 if (HAVE_ftrunctf2)
4470 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
4471 #endif
4472 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4473
4474 #ifdef HAVE_andqi3
4475 if (HAVE_andqi3)
4476 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
4477 #endif
4478 #ifdef HAVE_andhi3
4479 if (HAVE_andhi3)
4480 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
4481 #endif
4482 #ifdef HAVE_andpsi3
4483 if (HAVE_andpsi3)
4484 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
4485 #endif
4486 #ifdef HAVE_andsi3
4487 if (HAVE_andsi3)
4488 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
4489 #endif
4490 #ifdef HAVE_anddi3
4491 if (HAVE_anddi3)
4492 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
4493 #endif
4494 #ifdef HAVE_andti3
4495 if (HAVE_andti3)
4496 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
4497 #endif
4498 init_integral_libfuncs (and_optab, "and", '3');
4499
4500 #ifdef HAVE_iorqi3
4501 if (HAVE_iorqi3)
4502 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
4503 #endif
4504 #ifdef HAVE_iorhi3
4505 if (HAVE_iorhi3)
4506 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
4507 #endif
4508 #ifdef HAVE_iorpsi3
4509 if (HAVE_iorpsi3)
4510 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
4511 #endif
4512 #ifdef HAVE_iorsi3
4513 if (HAVE_iorsi3)
4514 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
4515 #endif
4516 #ifdef HAVE_iordi3
4517 if (HAVE_iordi3)
4518 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
4519 #endif
4520 #ifdef HAVE_iorti3
4521 if (HAVE_iorti3)
4522 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
4523 #endif
4524 init_integral_libfuncs (ior_optab, "ior", '3');
4525
4526 #ifdef HAVE_xorqi3
4527 if (HAVE_xorqi3)
4528 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
4529 #endif
4530 #ifdef HAVE_xorhi3
4531 if (HAVE_xorhi3)
4532 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
4533 #endif
4534 #ifdef HAVE_xorpsi3
4535 if (HAVE_xorpsi3)
4536 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
4537 #endif
4538 #ifdef HAVE_xorsi3
4539 if (HAVE_xorsi3)
4540 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
4541 #endif
4542 #ifdef HAVE_xordi3
4543 if (HAVE_xordi3)
4544 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
4545 #endif
4546 #ifdef HAVE_xorti3
4547 if (HAVE_xorti3)
4548 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
4549 #endif
4550 init_integral_libfuncs (xor_optab, "xor", '3');
4551
4552 #ifdef HAVE_ashlqi3
4553 if (HAVE_ashlqi3)
4554 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
4555 #endif
4556 #ifdef HAVE_ashlhi3
4557 if (HAVE_ashlhi3)
4558 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
4559 #endif
4560 #ifdef HAVE_ashlpsi3
4561 if (HAVE_ashlpsi3)
4562 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
4563 #endif
4564 #ifdef HAVE_ashlsi3
4565 if (HAVE_ashlsi3)
4566 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
4567 #endif
4568 #ifdef HAVE_ashldi3
4569 if (HAVE_ashldi3)
4570 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
4571 #endif
4572 #ifdef HAVE_ashlti3
4573 if (HAVE_ashlti3)
4574 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
4575 #endif
4576 init_integral_libfuncs (ashl_optab, "ashl", '3');
4577
4578 #ifdef HAVE_ashrqi3
4579 if (HAVE_ashrqi3)
4580 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
4581 #endif
4582 #ifdef HAVE_ashrhi3
4583 if (HAVE_ashrhi3)
4584 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
4585 #endif
4586 #ifdef HAVE_ashrpsi3
4587 if (HAVE_ashrpsi3)
4588 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
4589 #endif
4590 #ifdef HAVE_ashrsi3
4591 if (HAVE_ashrsi3)
4592 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
4593 #endif
4594 #ifdef HAVE_ashrdi3
4595 if (HAVE_ashrdi3)
4596 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
4597 #endif
4598 #ifdef HAVE_ashrti3
4599 if (HAVE_ashrti3)
4600 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
4601 #endif
4602 init_integral_libfuncs (ashr_optab, "ashr", '3');
4603
4604 #ifdef HAVE_lshlqi3
4605 if (HAVE_lshlqi3)
4606 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
4607 #endif
4608 #ifdef HAVE_lshlhi3
4609 if (HAVE_lshlhi3)
4610 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
4611 #endif
4612 #ifdef HAVE_lshlpsi3
4613 if (HAVE_lshlpsi3)
4614 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
4615 #endif
4616 #ifdef HAVE_lshlsi3
4617 if (HAVE_lshlsi3)
4618 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
4619 #endif
4620 #ifdef HAVE_lshldi3
4621 if (HAVE_lshldi3)
4622 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
4623 #endif
4624 #ifdef HAVE_lshlti3
4625 if (HAVE_lshlti3)
4626 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
4627 #endif
4628 init_integral_libfuncs (lshl_optab, "lshl", '3');
4629
4630 #ifdef HAVE_lshrqi3
4631 if (HAVE_lshrqi3)
4632 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
4633 #endif
4634 #ifdef HAVE_lshrhi3
4635 if (HAVE_lshrhi3)
4636 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
4637 #endif
4638 #ifdef HAVE_lshrpsi3
4639 if (HAVE_lshrpsi3)
4640 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
4641 #endif
4642 #ifdef HAVE_lshrsi3
4643 if (HAVE_lshrsi3)
4644 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
4645 #endif
4646 #ifdef HAVE_lshrdi3
4647 if (HAVE_lshrdi3)
4648 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
4649 #endif
4650 #ifdef HAVE_lshrti3
4651 if (HAVE_lshrti3)
4652 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
4653 #endif
4654 init_integral_libfuncs (lshr_optab, "lshr", '3');
4655
4656 #ifdef HAVE_rotlqi3
4657 if (HAVE_rotlqi3)
4658 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
4659 #endif
4660 #ifdef HAVE_rotlhi3
4661 if (HAVE_rotlhi3)
4662 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
4663 #endif
4664 #ifdef HAVE_rotlpsi3
4665 if (HAVE_rotlpsi3)
4666 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
4667 #endif
4668 #ifdef HAVE_rotlsi3
4669 if (HAVE_rotlsi3)
4670 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
4671 #endif
4672 #ifdef HAVE_rotldi3
4673 if (HAVE_rotldi3)
4674 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
4675 #endif
4676 #ifdef HAVE_rotlti3
4677 if (HAVE_rotlti3)
4678 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
4679 #endif
4680 init_integral_libfuncs (rotl_optab, "rotl", '3');
4681
4682 #ifdef HAVE_rotrqi3
4683 if (HAVE_rotrqi3)
4684 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
4685 #endif
4686 #ifdef HAVE_rotrhi3
4687 if (HAVE_rotrhi3)
4688 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
4689 #endif
4690 #ifdef HAVE_rotrpsi3
4691 if (HAVE_rotrpsi3)
4692 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4693 #endif
4694 #ifdef HAVE_rotrsi3
4695 if (HAVE_rotrsi3)
4696 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4697 #endif
4698 #ifdef HAVE_rotrdi3
4699 if (HAVE_rotrdi3)
4700 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4701 #endif
4702 #ifdef HAVE_rotrti3
4703 if (HAVE_rotrti3)
4704 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4705 #endif
4706 init_integral_libfuncs (rotr_optab, "rotr", '3');
4707
4708 #ifdef HAVE_sminqi3
4709 if (HAVE_sminqi3)
4710 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4711 #endif
4712 #ifdef HAVE_sminhi3
4713 if (HAVE_sminhi3)
4714 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4715 #endif
4716 #ifdef HAVE_sminsi3
4717 if (HAVE_sminsi3)
4718 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4719 #endif
4720 #ifdef HAVE_smindi3
4721 if (HAVE_smindi3)
4722 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4723 #endif
4724 #ifdef HAVE_sminti3
4725 if (HAVE_sminti3)
4726 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4727 #endif
4728 #ifdef HAVE_minqf3
4729 if (HAVE_minqf3)
4730 smin_optab->handlers[(int) QFmode].insn_code = CODE_FOR_minqf3;
4731 #endif
4732 #ifdef HAVE_minhf3
4733 if (HAVE_minhf3)
4734 smin_optab->handlers[(int) HFmode].insn_code = CODE_FOR_minhf3;
4735 #endif
4736 #ifdef HAVE_minsf3
4737 if (HAVE_minsf3)
4738 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4739 #endif
4740 #ifdef HAVE_mindf3
4741 if (HAVE_mindf3)
4742 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4743 #endif
4744 #ifdef HAVE_minxf3
4745 if (HAVE_minxf3)
4746 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4747 #endif
4748 #ifdef HAVE_mintf3
4749 if (HAVE_mintf3)
4750 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4751 #endif
4752 init_integral_libfuncs (smin_optab, "min", '3');
4753 init_floating_libfuncs (smin_optab, "min", '3');
4754
4755 #ifdef HAVE_smaxqi3
4756 if (HAVE_smaxqi3)
4757 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4758 #endif
4759 #ifdef HAVE_smaxhi3
4760 if (HAVE_smaxhi3)
4761 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4762 #endif
4763 #ifdef HAVE_smaxsi3
4764 if (HAVE_smaxsi3)
4765 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4766 #endif
4767 #ifdef HAVE_smaxdi3
4768 if (HAVE_smaxdi3)
4769 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4770 #endif
4771 #ifdef HAVE_smaxti3
4772 if (HAVE_smaxti3)
4773 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4774 #endif
4775 #ifdef HAVE_maxqf3
4776 if (HAVE_maxqf3)
4777 smax_optab->handlers[(int) QFmode].insn_code = CODE_FOR_maxqf3;
4778 #endif
4779 #ifdef HAVE_maxhf3
4780 if (HAVE_maxhf3)
4781 smax_optab->handlers[(int) HFmode].insn_code = CODE_FOR_maxhf3;
4782 #endif
4783 #ifdef HAVE_maxsf3
4784 if (HAVE_maxsf3)
4785 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4786 #endif
4787 #ifdef HAVE_maxdf3
4788 if (HAVE_maxdf3)
4789 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4790 #endif
4791 #ifdef HAVE_maxxf3
4792 if (HAVE_maxxf3)
4793 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4794 #endif
4795 #ifdef HAVE_maxtf3
4796 if (HAVE_maxtf3)
4797 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4798 #endif
4799 init_integral_libfuncs (smax_optab, "max", '3');
4800 init_floating_libfuncs (smax_optab, "max", '3');
4801
4802 #ifdef HAVE_uminqi3
4803 if (HAVE_uminqi3)
4804 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4805 #endif
4806 #ifdef HAVE_uminhi3
4807 if (HAVE_uminhi3)
4808 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4809 #endif
4810 #ifdef HAVE_uminsi3
4811 if (HAVE_uminsi3)
4812 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4813 #endif
4814 #ifdef HAVE_umindi3
4815 if (HAVE_umindi3)
4816 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4817 #endif
4818 #ifdef HAVE_uminti3
4819 if (HAVE_uminti3)
4820 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4821 #endif
4822 init_integral_libfuncs (umin_optab, "umin", '3');
4823
4824 #ifdef HAVE_umaxqi3
4825 if (HAVE_umaxqi3)
4826 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4827 #endif
4828 #ifdef HAVE_umaxhi3
4829 if (HAVE_umaxhi3)
4830 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4831 #endif
4832 #ifdef HAVE_umaxsi3
4833 if (HAVE_umaxsi3)
4834 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4835 #endif
4836 #ifdef HAVE_umaxdi3
4837 if (HAVE_umaxdi3)
4838 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4839 #endif
4840 #ifdef HAVE_umaxti3
4841 if (HAVE_umaxti3)
4842 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4843 #endif
4844 init_integral_libfuncs (umax_optab, "umax", '3');
4845
4846 #ifdef HAVE_negqi2
4847 if (HAVE_negqi2)
4848 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4849 #endif
4850 #ifdef HAVE_neghi2
4851 if (HAVE_neghi2)
4852 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4853 #endif
4854 #ifdef HAVE_negpsi2
4855 if (HAVE_negpsi2)
4856 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4857 #endif
4858 #ifdef HAVE_negsi2
4859 if (HAVE_negsi2)
4860 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4861 #endif
4862 #ifdef HAVE_negdi2
4863 if (HAVE_negdi2)
4864 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4865 #endif
4866 #ifdef HAVE_negti2
4867 if (HAVE_negti2)
4868 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4869 #endif
4870 #ifdef HAVE_negqf2
4871 if (HAVE_negqf2)
4872 neg_optab->handlers[(int) QFmode].insn_code = CODE_FOR_negqf2;
4873 #endif
4874 #ifdef HAVE_neghf2
4875 if (HAVE_neghf2)
4876 neg_optab->handlers[(int) HFmode].insn_code = CODE_FOR_neghf2;
4877 #endif
4878 #ifdef HAVE_negsf2
4879 if (HAVE_negsf2)
4880 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4881 #endif
4882 #ifdef HAVE_negdf2
4883 if (HAVE_negdf2)
4884 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4885 #endif
4886 #ifdef HAVE_negxf2
4887 if (HAVE_negxf2)
4888 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4889 #endif
4890 #ifdef HAVE_negtf2
4891 if (HAVE_negtf2)
4892 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4893 #endif
4894 init_integral_libfuncs (neg_optab, "neg", '2');
4895 init_floating_libfuncs (neg_optab, "neg", '2');
4896
4897 #ifdef HAVE_absqi2
4898 if (HAVE_absqi2)
4899 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4900 #endif
4901 #ifdef HAVE_abshi2
4902 if (HAVE_abshi2)
4903 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4904 #endif
4905 #ifdef HAVE_abspsi2
4906 if (HAVE_abspsi2)
4907 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4908 #endif
4909 #ifdef HAVE_abssi2
4910 if (HAVE_abssi2)
4911 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4912 #endif
4913 #ifdef HAVE_absdi2
4914 if (HAVE_absdi2)
4915 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4916 #endif
4917 #ifdef HAVE_absti2
4918 if (HAVE_absti2)
4919 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4920 #endif
4921 #ifdef HAVE_absqf2
4922 if (HAVE_absqf2)
4923 abs_optab->handlers[(int) QFmode].insn_code = CODE_FOR_absqf2;
4924 #endif
4925 #ifdef HAVE_abshf2
4926 if (HAVE_abshf2)
4927 abs_optab->handlers[(int) HFmode].insn_code = CODE_FOR_abshf2;
4928 #endif
4929 #ifdef HAVE_abssf2
4930 if (HAVE_abssf2)
4931 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4932 #endif
4933 #ifdef HAVE_absdf2
4934 if (HAVE_absdf2)
4935 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4936 #endif
4937 #ifdef HAVE_absxf2
4938 if (HAVE_absxf2)
4939 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4940 #endif
4941 #ifdef HAVE_abstf2
4942 if (HAVE_abstf2)
4943 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4944 #endif
4945
4946 /* Use cabs for DC complex abs, since systems generally have cabs.
4947 Don't define any libcall for SCmode, so that cabs will be used. */
4948 abs_optab->handlers[(int) DCmode].libfunc
4949 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4950
4951 #ifdef HAVE_sqrtqi2
4952 if (HAVE_sqrtqi2)
4953 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4954 #endif
4955 #ifdef HAVE_sqrthi2
4956 if (HAVE_sqrthi2)
4957 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4958 #endif
4959 #ifdef HAVE_sqrtpsi2
4960 if (HAVE_sqrtpsi2)
4961 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4962 #endif
4963 #ifdef HAVE_sqrtsi2
4964 if (HAVE_sqrtsi2)
4965 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4966 #endif
4967 #ifdef HAVE_sqrtdi2
4968 if (HAVE_sqrtdi2)
4969 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4970 #endif
4971 #ifdef HAVE_sqrtti2
4972 if (HAVE_sqrtti2)
4973 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4974 #endif
4975 #ifdef HAVE_sqrtqf2
4976 if (HAVE_sqrtqf2)
4977 sqrt_optab->handlers[(int) QFmode].insn_code = CODE_FOR_sqrtqf2;
4978 #endif
4979 #ifdef HAVE_sqrthf2
4980 if (HAVE_sqrthf2)
4981 sqrt_optab->handlers[(int) HFmode].insn_code = CODE_FOR_sqrthf2;
4982 #endif
4983 #ifdef HAVE_sqrtsf2
4984 if (HAVE_sqrtsf2)
4985 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4986 #endif
4987 #ifdef HAVE_sqrtdf2
4988 if (HAVE_sqrtdf2)
4989 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4990 #endif
4991 #ifdef HAVE_sqrttf2
4992 if (HAVE_sqrttf2)
4993 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4994 #endif
4995 /* No library calls here! If there is no sqrt instruction expand_builtin
4996 should force the library call. */
4997
4998 #ifdef HAVE_sinqf2
4999 if (HAVE_sinqf2)
5000 sin_optab->handlers[(int) QFmode].insn_code = CODE_FOR_sinqf2;
5001 #endif
5002 #ifdef HAVE_sinhf2
5003 if (HAVE_sinhf2)
5004 sin_optab->handlers[(int) HFmode].insn_code = CODE_FOR_sinhf2;
5005 #endif
5006 #ifdef HAVE_sinsf2
5007 if (HAVE_sinsf2)
5008 sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
5009 #endif
5010 #ifdef HAVE_sindf2
5011 if (HAVE_sindf2)
5012 sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
5013 #endif
5014 #ifdef HAVE_sintf2
5015 if (HAVE_sintf2)
5016 sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
5017 #endif
5018 /* No library calls here! If there is no sin instruction expand_builtin
5019 should force the library call. */
5020
5021 #ifdef HAVE_cosqf2
5022 if (HAVE_cosqf2)
5023 cos_optab->handlers[(int) QFmode].insn_code = CODE_FOR_cosqf2;
5024 #endif
5025 #ifdef HAVE_coshf2
5026 if (HAVE_coshf2)
5027 cos_optab->handlers[(int) HFmode].insn_code = CODE_FOR_coshf2;
5028 #endif
5029 #ifdef HAVE_cossf2
5030 if (HAVE_cossf2)
5031 cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
5032 #endif
5033 #ifdef HAVE_cosdf2
5034 if (HAVE_cosdf2)
5035 cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
5036 #endif
5037 #ifdef HAVE_costf2
5038 if (HAVE_costf2)
5039 cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
5040 #endif
5041 /* No library calls here! If there is no cos instruction expand_builtin
5042 should force the library call. */
5043
5044 #ifdef HAVE_strlenqi
5045 if (HAVE_strlenqi)
5046 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
5047 #endif
5048 #ifdef HAVE_strlenhi
5049 if (HAVE_strlenhi)
5050 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
5051 #endif
5052 #ifdef HAVE_strlenpsi
5053 if (HAVE_strlenpsi)
5054 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
5055 #endif
5056 #ifdef HAVE_strlensi
5057 if (HAVE_strlensi)
5058 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
5059 #endif
5060 #ifdef HAVE_strlendi
5061 if (HAVE_strlendi)
5062 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
5063 #endif
5064 #ifdef HAVE_strlenti
5065 if (HAVE_strlenti)
5066 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
5067 #endif
5068 /* No library calls here! If there is no strlen instruction expand_builtin
5069 should force the library call. */
5070
5071 #ifdef HAVE_one_cmplqi2
5072 if (HAVE_one_cmplqi2)
5073 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
5074 #endif
5075 #ifdef HAVE_one_cmplhi2
5076 if (HAVE_one_cmplhi2)
5077 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
5078 #endif
5079 #ifdef HAVE_one_cmplpsi2
5080 if (HAVE_one_cmplpsi2)
5081 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
5082 #endif
5083 #ifdef HAVE_one_cmplsi2
5084 if (HAVE_one_cmplsi2)
5085 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
5086 #endif
5087 #ifdef HAVE_one_cmpldi2
5088 if (HAVE_one_cmpldi2)
5089 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
5090 #endif
5091 #ifdef HAVE_one_cmplti2
5092 if (HAVE_one_cmplti2)
5093 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
5094 #endif
5095 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5096
5097 #ifdef HAVE_ffsqi2
5098 if (HAVE_ffsqi2)
5099 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
5100 #endif
5101 #ifdef HAVE_ffshi2
5102 if (HAVE_ffshi2)
5103 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
5104 #endif
5105 #ifdef HAVE_ffspsi2
5106 if (HAVE_ffspsi2)
5107 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
5108 #endif
5109 #ifdef HAVE_ffssi2
5110 if (HAVE_ffssi2)
5111 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
5112 #endif
5113 #ifdef HAVE_ffsdi2
5114 if (HAVE_ffsdi2)
5115 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
5116 #endif
5117 #ifdef HAVE_ffsti2
5118 if (HAVE_ffsti2)
5119 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
5120 #endif
5121 init_integral_libfuncs (ffs_optab, "ffs", '2');
5122 ffs_optab->handlers[(int) SImode].libfunc
5123 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
5124
5125 #ifdef HAVE_movqi
5126 if (HAVE_movqi)
5127 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
5128 #endif
5129 #ifdef HAVE_movhi
5130 if (HAVE_movhi)
5131 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
5132 #endif
5133 #ifdef HAVE_movpsi
5134 if (HAVE_movpsi)
5135 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
5136 #endif
5137 #ifdef HAVE_movsi
5138 if (HAVE_movsi)
5139 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
5140 #endif
5141 #ifdef HAVE_movdi
5142 if (HAVE_movdi)
5143 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
5144 #endif
5145 #ifdef HAVE_movti
5146 if (HAVE_movti)
5147 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
5148 #endif
5149 #ifdef HAVE_movqf
5150 if (HAVE_movqf)
5151 mov_optab->handlers[(int) QFmode].insn_code = CODE_FOR_movqf;
5152 #endif
5153 #ifdef HAVE_movhf
5154 if (HAVE_movhf)
5155 mov_optab->handlers[(int) HFmode].insn_code = CODE_FOR_movhf;
5156 #endif
5157 #ifdef HAVE_movsf
5158 if (HAVE_movsf)
5159 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
5160 #endif
5161 #ifdef HAVE_movdf
5162 if (HAVE_movdf)
5163 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
5164 #endif
5165 #ifdef HAVE_movxf
5166 if (HAVE_movxf)
5167 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
5168 #endif
5169 #ifdef HAVE_movtf
5170 if (HAVE_movtf)
5171 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
5172 #endif
5173 #ifdef HAVE_movcc
5174 if (HAVE_movcc)
5175 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
5176 #endif
5177
5178 #ifdef EXTRA_CC_MODES
5179 init_mov_optab ();
5180 #endif
5181
5182 #ifdef HAVE_movstrictqi
5183 if (HAVE_movstrictqi)
5184 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
5185 #endif
5186 #ifdef HAVE_movstricthi
5187 if (HAVE_movstricthi)
5188 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
5189 #endif
5190 #ifdef HAVE_movstrictpsi
5191 if (HAVE_movstrictpsi)
5192 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
5193 #endif
5194 #ifdef HAVE_movstrictsi
5195 if (HAVE_movstrictsi)
5196 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
5197 #endif
5198 #ifdef HAVE_movstrictdi
5199 if (HAVE_movstrictdi)
5200 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
5201 #endif
5202 #ifdef HAVE_movstrictti
5203 if (HAVE_movstrictti)
5204 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
5205 #endif
5206
5207 #ifdef HAVE_cmpqi
5208 if (HAVE_cmpqi)
5209 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
5210 #endif
5211 #ifdef HAVE_cmphi
5212 if (HAVE_cmphi)
5213 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
5214 #endif
5215 #ifdef HAVE_cmppsi
5216 if (HAVE_cmppsi)
5217 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
5218 #endif
5219 #ifdef HAVE_cmpsi
5220 if (HAVE_cmpsi)
5221 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
5222 #endif
5223 #ifdef HAVE_cmpdi
5224 if (HAVE_cmpdi)
5225 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
5226 #endif
5227 #ifdef HAVE_cmpti
5228 if (HAVE_cmpti)
5229 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
5230 #endif
5231 #ifdef HAVE_cmpqf
5232 if (HAVE_cmpqf)
5233 cmp_optab->handlers[(int) QFmode].insn_code = CODE_FOR_cmpqf;
5234 #endif
5235 #ifdef HAVE_cmphf
5236 if (HAVE_cmphf)
5237 cmp_optab->handlers[(int) HFmode].insn_code = CODE_FOR_cmphf;
5238 #endif
5239 #ifdef HAVE_cmpsf
5240 if (HAVE_cmpsf)
5241 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
5242 #endif
5243 #ifdef HAVE_cmpdf
5244 if (HAVE_cmpdf)
5245 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
5246 #endif
5247 #ifdef HAVE_cmpxf
5248 if (HAVE_cmpxf)
5249 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
5250 #endif
5251 #ifdef HAVE_cmptf
5252 if (HAVE_cmptf)
5253 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
5254 #endif
5255 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
5256 init_integral_libfuncs (cmp_optab, "cmp", '2');
5257 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5258 init_floating_libfuncs (cmp_optab, "cmp", '2');
5259
5260 #ifdef HAVE_tstqi
5261 if (HAVE_tstqi)
5262 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
5263 #endif
5264 #ifdef HAVE_tsthi
5265 if (HAVE_tsthi)
5266 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
5267 #endif
5268 #ifdef HAVE_tstpsi
5269 if (HAVE_tstpsi)
5270 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
5271 #endif
5272 #ifdef HAVE_tstsi
5273 if (HAVE_tstsi)
5274 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
5275 #endif
5276 #ifdef HAVE_tstdi
5277 if (HAVE_tstdi)
5278 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
5279 #endif
5280 #ifdef HAVE_tstti
5281 if (HAVE_tstti)
5282 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
5283 #endif
5284 #ifdef HAVE_tstqf
5285 if (HAVE_tstqf)
5286 tst_optab->handlers[(int) QFmode].insn_code = CODE_FOR_tstqf;
5287 #endif
5288 #ifdef HAVE_tsthf
5289 if (HAVE_tsthf)
5290 tst_optab->handlers[(int) HFmode].insn_code = CODE_FOR_tsthf;
5291 #endif
5292 #ifdef HAVE_tstsf
5293 if (HAVE_tstsf)
5294 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
5295 #endif
5296 #ifdef HAVE_tstdf
5297 if (HAVE_tstdf)
5298 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
5299 #endif
5300 #ifdef HAVE_tstxf
5301 if (HAVE_tstxf)
5302 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
5303 #endif
5304 #ifdef HAVE_tsttf
5305 if (HAVE_tsttf)
5306 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
5307 #endif
5308
5309 #ifdef HAVE_beq
5310 if (HAVE_beq)
5311 bcc_gen_fctn[(int) EQ] = gen_beq;
5312 #endif
5313 #ifdef HAVE_bne
5314 if (HAVE_bne)
5315 bcc_gen_fctn[(int) NE] = gen_bne;
5316 #endif
5317 #ifdef HAVE_bgt
5318 if (HAVE_bgt)
5319 bcc_gen_fctn[(int) GT] = gen_bgt;
5320 #endif
5321 #ifdef HAVE_bge
5322 if (HAVE_bge)
5323 bcc_gen_fctn[(int) GE] = gen_bge;
5324 #endif
5325 #ifdef HAVE_bgtu
5326 if (HAVE_bgtu)
5327 bcc_gen_fctn[(int) GTU] = gen_bgtu;
5328 #endif
5329 #ifdef HAVE_bgeu
5330 if (HAVE_bgeu)
5331 bcc_gen_fctn[(int) GEU] = gen_bgeu;
5332 #endif
5333 #ifdef HAVE_blt
5334 if (HAVE_blt)
5335 bcc_gen_fctn[(int) LT] = gen_blt;
5336 #endif
5337 #ifdef HAVE_ble
5338 if (HAVE_ble)
5339 bcc_gen_fctn[(int) LE] = gen_ble;
5340 #endif
5341 #ifdef HAVE_bltu
5342 if (HAVE_bltu)
5343 bcc_gen_fctn[(int) LTU] = gen_bltu;
5344 #endif
5345 #ifdef HAVE_bleu
5346 if (HAVE_bleu)
5347 bcc_gen_fctn[(int) LEU] = gen_bleu;
5348 #endif
5349
5350 for (i = 0; i < NUM_RTX_CODE; i++)
5351 setcc_gen_code[i] = CODE_FOR_nothing;
5352
5353 #ifdef HAVE_seq
5354 if (HAVE_seq)
5355 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
5356 #endif
5357 #ifdef HAVE_sne
5358 if (HAVE_sne)
5359 setcc_gen_code[(int) NE] = CODE_FOR_sne;
5360 #endif
5361 #ifdef HAVE_sgt
5362 if (HAVE_sgt)
5363 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
5364 #endif
5365 #ifdef HAVE_sge
5366 if (HAVE_sge)
5367 setcc_gen_code[(int) GE] = CODE_FOR_sge;
5368 #endif
5369 #ifdef HAVE_sgtu
5370 if (HAVE_sgtu)
5371 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
5372 #endif
5373 #ifdef HAVE_sgeu
5374 if (HAVE_sgeu)
5375 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
5376 #endif
5377 #ifdef HAVE_slt
5378 if (HAVE_slt)
5379 setcc_gen_code[(int) LT] = CODE_FOR_slt;
5380 #endif
5381 #ifdef HAVE_sle
5382 if (HAVE_sle)
5383 setcc_gen_code[(int) LE] = CODE_FOR_sle;
5384 #endif
5385 #ifdef HAVE_sltu
5386 if (HAVE_sltu)
5387 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
5388 #endif
5389 #ifdef HAVE_sleu
5390 if (HAVE_sleu)
5391 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
5392 #endif
5393
5394 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
5395 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
5396 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
5397 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
5398 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
5399
5400 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
5401 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
5402 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
5403 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
5404 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
5405
5406 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
5407 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
5408 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
5409 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
5410 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
5411 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
5412
5413 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
5414 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
5415 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
5416 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
5417 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
5418 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
5419
5420 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
5421 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
5422 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
5423 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
5424 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
5425 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
5426
5427 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
5428 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
5429 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
5430 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
5431 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
5432 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
5433
5434 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
5435 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
5436 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
5437 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
5438 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
5439 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
5440
5441 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
5442 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
5443 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
5444
5445 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
5446 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
5447 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
5448
5449 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
5450 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
5451 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
5452
5453 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
5454 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
5455 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
5456
5457 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
5458 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
5459 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
5460
5461 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
5462 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
5463 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
5464
5465 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
5466 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
5467 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
5468
5469 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
5470 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
5471 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
5472
5473 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
5474 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
5475 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
5476
5477 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
5478 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
5479 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
5480
5481 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
5482 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
5483 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
5484
5485 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
5486 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
5487 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
5488 }
5489 \f
5490 #ifdef BROKEN_LDEXP
5491
5492 /* SCO 3.2 apparently has a broken ldexp. */
5493
5494 double
5495 ldexp(x,n)
5496 double x;
5497 int n;
5498 {
5499 if (n > 0)
5500 while (n--)
5501 x *= 2;
5502
5503 return x;
5504 }
5505 #endif /* BROKEN_LDEXP */
This page took 0.273464 seconds and 6 git commands to generate.