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