]> gcc.gnu.org Git - gcc.git/blob - gcc/optabs.c
(expand_unop): Try subtraction from zero if there isn't a
[gcc.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include "config.h"
22 #include "rtl.h"
23 #include "tree.h"
24 #include "flags.h"
25 #include "insn-flags.h"
26 #include "insn-codes.h"
27 #include "expr.h"
28 #include "insn-config.h"
29 #include "recog.h"
30 #include "reload.h"
31 #include <ctype.h>
32
33 /* Each optab contains info on how this target machine
34 can perform a particular operation
35 for all sizes and kinds of operands.
36
37 The operation to be performed is often specified
38 by passing one of these optabs as an argument.
39
40 See expr.h for documentation of these optabs. */
41
42 optab add_optab;
43 optab sub_optab;
44 optab smul_optab;
45 optab smul_highpart_optab;
46 optab umul_highpart_optab;
47 optab smul_widen_optab;
48 optab umul_widen_optab;
49 optab sdiv_optab;
50 optab sdivmod_optab;
51 optab udiv_optab;
52 optab udivmod_optab;
53 optab smod_optab;
54 optab umod_optab;
55 optab flodiv_optab;
56 optab ftrunc_optab;
57 optab and_optab;
58 optab ior_optab;
59 optab xor_optab;
60 optab ashl_optab;
61 optab lshr_optab;
62 optab ashr_optab;
63 optab rotl_optab;
64 optab rotr_optab;
65 optab smin_optab;
66 optab smax_optab;
67 optab umin_optab;
68 optab umax_optab;
69
70 optab mov_optab;
71 optab movstrict_optab;
72
73 optab neg_optab;
74 optab abs_optab;
75 optab one_cmpl_optab;
76 optab ffs_optab;
77 optab sqrt_optab;
78 optab sin_optab;
79 optab cos_optab;
80
81 optab cmp_optab;
82 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
83 optab tst_optab;
84
85 optab strlen_optab;
86
87 /* Tables of patterns for extending one integer mode to another. */
88 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
89
90 /* Tables of patterns for converting between fixed and floating point. */
91 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
92 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94
95 /* Contains the optab used for each rtx code. */
96 optab code_to_optab[NUM_RTX_CODE + 1];
97
98 /* SYMBOL_REF rtx's for the library functions that are called
99 implicitly and not via optabs. */
100
101 rtx extendsfdf2_libfunc;
102 rtx extendsfxf2_libfunc;
103 rtx extendsftf2_libfunc;
104 rtx extenddfxf2_libfunc;
105 rtx extenddftf2_libfunc;
106
107 rtx truncdfsf2_libfunc;
108 rtx truncxfsf2_libfunc;
109 rtx trunctfsf2_libfunc;
110 rtx truncxfdf2_libfunc;
111 rtx trunctfdf2_libfunc;
112
113 rtx memcpy_libfunc;
114 rtx bcopy_libfunc;
115 rtx memcmp_libfunc;
116 rtx bcmp_libfunc;
117 rtx memset_libfunc;
118 rtx bzero_libfunc;
119
120 rtx eqhf2_libfunc;
121 rtx nehf2_libfunc;
122 rtx gthf2_libfunc;
123 rtx gehf2_libfunc;
124 rtx lthf2_libfunc;
125 rtx lehf2_libfunc;
126
127 rtx eqsf2_libfunc;
128 rtx nesf2_libfunc;
129 rtx gtsf2_libfunc;
130 rtx gesf2_libfunc;
131 rtx ltsf2_libfunc;
132 rtx lesf2_libfunc;
133
134 rtx eqdf2_libfunc;
135 rtx nedf2_libfunc;
136 rtx gtdf2_libfunc;
137 rtx gedf2_libfunc;
138 rtx ltdf2_libfunc;
139 rtx ledf2_libfunc;
140
141 rtx eqxf2_libfunc;
142 rtx nexf2_libfunc;
143 rtx gtxf2_libfunc;
144 rtx gexf2_libfunc;
145 rtx ltxf2_libfunc;
146 rtx lexf2_libfunc;
147
148 rtx eqtf2_libfunc;
149 rtx netf2_libfunc;
150 rtx gttf2_libfunc;
151 rtx getf2_libfunc;
152 rtx lttf2_libfunc;
153 rtx letf2_libfunc;
154
155 rtx floatsisf_libfunc;
156 rtx floatdisf_libfunc;
157 rtx floattisf_libfunc;
158
159 rtx floatsidf_libfunc;
160 rtx floatdidf_libfunc;
161 rtx floattidf_libfunc;
162
163 rtx floatsixf_libfunc;
164 rtx floatdixf_libfunc;
165 rtx floattixf_libfunc;
166
167 rtx floatsitf_libfunc;
168 rtx floatditf_libfunc;
169 rtx floattitf_libfunc;
170
171 rtx fixsfsi_libfunc;
172 rtx fixsfdi_libfunc;
173 rtx fixsfti_libfunc;
174
175 rtx fixdfsi_libfunc;
176 rtx fixdfdi_libfunc;
177 rtx fixdfti_libfunc;
178
179 rtx fixxfsi_libfunc;
180 rtx fixxfdi_libfunc;
181 rtx fixxfti_libfunc;
182
183 rtx fixtfsi_libfunc;
184 rtx fixtfdi_libfunc;
185 rtx fixtfti_libfunc;
186
187 rtx fixunssfsi_libfunc;
188 rtx fixunssfdi_libfunc;
189 rtx fixunssfti_libfunc;
190
191 rtx fixunsdfsi_libfunc;
192 rtx fixunsdfdi_libfunc;
193 rtx fixunsdfti_libfunc;
194
195 rtx fixunsxfsi_libfunc;
196 rtx fixunsxfdi_libfunc;
197 rtx fixunsxfti_libfunc;
198
199 rtx fixunstfsi_libfunc;
200 rtx fixunstfdi_libfunc;
201 rtx fixunstfti_libfunc;
202
203 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
204 gives the gen_function to make a branch to test that condition. */
205
206 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
207
208 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
209 gives the insn code to make a store-condition insn
210 to test that condition. */
211
212 enum insn_code setcc_gen_code[NUM_RTX_CODE];
213
214 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
215 static rtx widen_operand PROTO((rtx, enum machine_mode,
216 enum machine_mode, int, int));
217 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
218 int, int *));
219 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
220 int));
221 static rtx ftruncify PROTO((rtx));
222 static optab init_optab PROTO((enum rtx_code));
223 static void init_libfuncs PROTO((optab, int, int, char *, int));
224 static void init_integral_libfuncs PROTO((optab, char *, int));
225 static void init_floating_libfuncs PROTO((optab, char *, int));
226 static void init_complex_libfuncs PROTO((optab, char *, int));
227 \f
228 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
229 the result of operation CODE applied to OP0 (and OP1 if it is a binary
230 operation).
231
232 If the last insn does not set TARGET, don't do anything, but return 1.
233
234 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
235 don't add the REG_EQUAL note but return 0. Our caller can then try
236 again, ensuring that TARGET is not one of the operands. */
237
238 static int
239 add_equal_note (seq, target, code, op0, op1)
240 rtx seq;
241 rtx target;
242 enum rtx_code code;
243 rtx op0, op1;
244 {
245 rtx set;
246 int i;
247 rtx note;
248
249 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
250 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
251 || GET_CODE (seq) != SEQUENCE
252 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
253 || GET_CODE (target) == ZERO_EXTRACT
254 || (! rtx_equal_p (SET_DEST (set), target)
255 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
256 SUBREG. */
257 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
258 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
259 target))))
260 return 1;
261
262 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
263 besides the last insn. */
264 if (reg_overlap_mentioned_p (target, op0)
265 || (op1 && reg_overlap_mentioned_p (target, op1)))
266 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
267 if (reg_set_p (target, XVECEXP (seq, 0, i)))
268 return 0;
269
270 if (GET_RTX_CLASS (code) == '1')
271 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
272 else
273 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
274
275 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
276 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
277 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
278
279 return 1;
280 }
281 \f
282 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
283 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
284 not actually do a sign-extend or zero-extend, but can leave the
285 higher-order bits of the result rtx undefined, for example, in the case
286 of logical operations, but not right shifts. */
287
288 static rtx
289 widen_operand (op, mode, oldmode, unsignedp, no_extend)
290 rtx op;
291 enum machine_mode mode, oldmode;
292 int unsignedp;
293 int no_extend;
294 {
295 rtx result;
296
297 /* If we must extend do so. If OP is either a constant or a SUBREG
298 for a promoted object, also extend since it will be more efficient to
299 do so. */
300 if (! no_extend
301 || GET_MODE (op) == VOIDmode
302 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
303 return convert_modes (mode, oldmode, op, unsignedp);
304
305 /* If MODE is no wider than a single word, we return a paradoxical
306 SUBREG. */
307 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
308 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
309
310 /* Otherwise, get an object of MODE, clobber it, and set the low-order
311 part to OP. */
312
313 result = gen_reg_rtx (mode);
314 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
315 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
316 return result;
317 }
318 \f
319 /* Generate code to perform an operation specified by BINOPTAB
320 on operands OP0 and OP1, with result having machine-mode MODE.
321
322 UNSIGNEDP is for the case where we have to widen the operands
323 to perform the operation. It says to use zero-extension.
324
325 If TARGET is nonzero, the value
326 is generated there, if it is convenient to do so.
327 In all cases an rtx is returned for the locus of the value;
328 this may or may not be TARGET. */
329
330 rtx
331 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
332 enum machine_mode mode;
333 optab binoptab;
334 rtx op0, op1;
335 rtx target;
336 int unsignedp;
337 enum optab_methods methods;
338 {
339 enum optab_methods next_methods
340 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
341 ? OPTAB_WIDEN : methods);
342 enum mode_class class;
343 enum machine_mode wider_mode;
344 register rtx temp;
345 int commutative_op = 0;
346 int shift_op = (binoptab->code == ASHIFT
347 || binoptab->code == ASHIFTRT
348 || binoptab->code == LSHIFTRT
349 || binoptab->code == ROTATE
350 || binoptab->code == ROTATERT);
351 rtx entry_last = get_last_insn ();
352 rtx last;
353
354 class = GET_MODE_CLASS (mode);
355
356 op0 = protect_from_queue (op0, 0);
357 op1 = protect_from_queue (op1, 0);
358 if (target)
359 target = protect_from_queue (target, 1);
360
361 if (flag_force_mem)
362 {
363 op0 = force_not_mem (op0);
364 op1 = force_not_mem (op1);
365 }
366
367 /* If subtracting an integer constant, convert this into an addition of
368 the negated constant. */
369
370 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
371 {
372 op1 = negate_rtx (mode, op1);
373 binoptab = add_optab;
374 }
375
376 /* If we are inside an appropriately-short loop and one operand is an
377 expensive constant, force it into a register. */
378 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
379 && rtx_cost (op0, binoptab->code) > 2)
380 op0 = force_reg (mode, op0);
381
382 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
383 && rtx_cost (op1, binoptab->code) > 2)
384 op1 = force_reg (shift_op ? word_mode : mode, op1);
385
386 /* Record where to delete back to if we backtrack. */
387 last = get_last_insn ();
388
389 /* If operation is commutative,
390 try to make the first operand a register.
391 Even better, try to make it the same as the target.
392 Also try to make the last operand a constant. */
393 if (GET_RTX_CLASS (binoptab->code) == 'c'
394 || binoptab == smul_widen_optab
395 || binoptab == umul_widen_optab
396 || binoptab == smul_highpart_optab
397 || binoptab == umul_highpart_optab)
398 {
399 commutative_op = 1;
400
401 if (((target == 0 || GET_CODE (target) == REG)
402 ? ((GET_CODE (op1) == REG
403 && GET_CODE (op0) != REG)
404 || target == op1)
405 : rtx_equal_p (op1, target))
406 || GET_CODE (op0) == CONST_INT)
407 {
408 temp = op1;
409 op1 = op0;
410 op0 = temp;
411 }
412 }
413
414 /* If we can do it with a three-operand insn, do so. */
415
416 if (methods != OPTAB_MUST_WIDEN
417 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
418 {
419 int icode = (int) binoptab->handlers[(int) mode].insn_code;
420 enum machine_mode mode0 = insn_operand_mode[icode][1];
421 enum machine_mode mode1 = insn_operand_mode[icode][2];
422 rtx pat;
423 rtx xop0 = op0, xop1 = op1;
424
425 if (target)
426 temp = target;
427 else
428 temp = gen_reg_rtx (mode);
429
430 /* If it is a commutative operator and the modes would match
431 if we would swap the operands, we can save the conversions. */
432 if (commutative_op)
433 {
434 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
435 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
436 {
437 register rtx tmp;
438
439 tmp = op0; op0 = op1; op1 = tmp;
440 tmp = xop0; xop0 = xop1; xop1 = tmp;
441 }
442 }
443
444 /* In case the insn wants input operands in modes different from
445 the result, convert the operands. */
446
447 if (GET_MODE (op0) != VOIDmode
448 && GET_MODE (op0) != mode0)
449 xop0 = convert_to_mode (mode0, xop0, unsignedp);
450
451 if (GET_MODE (xop1) != VOIDmode
452 && GET_MODE (xop1) != mode1)
453 xop1 = convert_to_mode (mode1, xop1, unsignedp);
454
455 /* Now, if insn's predicates don't allow our operands, put them into
456 pseudo regs. */
457
458 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
459 xop0 = copy_to_mode_reg (mode0, xop0);
460
461 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
462 xop1 = copy_to_mode_reg (mode1, xop1);
463
464 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
465 temp = gen_reg_rtx (mode);
466
467 pat = GEN_FCN (icode) (temp, xop0, xop1);
468 if (pat)
469 {
470 /* If PAT is a multi-insn sequence, try to add an appropriate
471 REG_EQUAL note to it. If we can't because TEMP conflicts with an
472 operand, call ourselves again, this time without a target. */
473 if (GET_CODE (pat) == SEQUENCE
474 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
475 {
476 delete_insns_since (last);
477 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
478 unsignedp, methods);
479 }
480
481 emit_insn (pat);
482 return temp;
483 }
484 else
485 delete_insns_since (last);
486 }
487
488 /* If this is a multiply, see if we can do a widening operation that
489 takes operands of this mode and makes a wider mode. */
490
491 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
492 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
493 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
494 != CODE_FOR_nothing))
495 {
496 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
497 unsignedp ? umul_widen_optab : smul_widen_optab,
498 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
499
500 if (temp != 0)
501 {
502 if (GET_MODE_CLASS (mode) == MODE_INT)
503 return gen_lowpart (mode, temp);
504 else
505 return convert_to_mode (mode, temp, unsignedp);
506 }
507 }
508
509 /* Look for a wider mode of the same class for which we think we
510 can open-code the operation. Check for a widening multiply at the
511 wider mode as well. */
512
513 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
514 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
515 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
516 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
517 {
518 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
519 || (binoptab == smul_optab
520 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
521 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
522 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
523 != CODE_FOR_nothing)))
524 {
525 rtx xop0 = op0, xop1 = op1;
526 int no_extend = 0;
527
528 /* For certain integer operations, we need not actually extend
529 the narrow operands, as long as we will truncate
530 the results to the same narrowness. */
531
532 if ((binoptab == ior_optab || binoptab == and_optab
533 || binoptab == xor_optab
534 || binoptab == add_optab || binoptab == sub_optab
535 || binoptab == smul_optab || binoptab == ashl_optab)
536 && class == MODE_INT)
537 no_extend = 1;
538
539 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
540
541 /* The second operand of a shift must always be extended. */
542 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
543 no_extend && binoptab != ashl_optab);
544
545 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
546 unsignedp, OPTAB_DIRECT);
547 if (temp)
548 {
549 if (class != MODE_INT)
550 {
551 if (target == 0)
552 target = gen_reg_rtx (mode);
553 convert_move (target, temp, 0);
554 return target;
555 }
556 else
557 return gen_lowpart (mode, temp);
558 }
559 else
560 delete_insns_since (last);
561 }
562 }
563
564 /* These can be done a word at a time. */
565 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
566 && class == MODE_INT
567 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
568 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
569 {
570 int i;
571 rtx insns;
572 rtx equiv_value;
573
574 /* If TARGET is the same as one of the operands, the REG_EQUAL note
575 won't be accurate, so use a new target. */
576 if (target == 0 || target == op0 || target == op1)
577 target = gen_reg_rtx (mode);
578
579 start_sequence ();
580
581 /* Do the actual arithmetic. */
582 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
583 {
584 rtx target_piece = operand_subword (target, i, 1, mode);
585 rtx x = expand_binop (word_mode, binoptab,
586 operand_subword_force (op0, i, mode),
587 operand_subword_force (op1, i, mode),
588 target_piece, unsignedp, next_methods);
589
590 if (x == 0)
591 break;
592
593 if (target_piece != x)
594 emit_move_insn (target_piece, x);
595 }
596
597 insns = get_insns ();
598 end_sequence ();
599
600 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
601 {
602 if (binoptab->code != UNKNOWN)
603 equiv_value
604 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
605 else
606 equiv_value = 0;
607
608 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
609 return target;
610 }
611 }
612
613 /* Synthesize double word shifts from single word shifts. */
614 if ((binoptab == lshr_optab || binoptab == ashl_optab
615 || binoptab == ashr_optab)
616 && class == MODE_INT
617 && GET_CODE (op1) == CONST_INT
618 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
619 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
620 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
621 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
622 {
623 rtx insns, inter, equiv_value;
624 rtx into_target, outof_target;
625 rtx into_input, outof_input;
626 int shift_count, left_shift, outof_word;
627
628 /* If TARGET is the same as one of the operands, the REG_EQUAL note
629 won't be accurate, so use a new target. */
630 if (target == 0 || target == op0 || target == op1)
631 target = gen_reg_rtx (mode);
632
633 start_sequence ();
634
635 shift_count = INTVAL (op1);
636
637 /* OUTOF_* is the word we are shifting bits away from, and
638 INTO_* is the word that we are shifting bits towards, thus
639 they differ depending on the direction of the shift and
640 WORDS_BIG_ENDIAN. */
641
642 left_shift = binoptab == ashl_optab;
643 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
644
645 outof_target = operand_subword (target, outof_word, 1, mode);
646 into_target = operand_subword (target, 1 - outof_word, 1, mode);
647
648 outof_input = operand_subword_force (op0, outof_word, mode);
649 into_input = operand_subword_force (op0, 1 - outof_word, mode);
650
651 if (shift_count >= BITS_PER_WORD)
652 {
653 inter = expand_binop (word_mode, binoptab,
654 outof_input,
655 GEN_INT (shift_count - BITS_PER_WORD),
656 into_target, unsignedp, next_methods);
657
658 if (inter != 0 && inter != into_target)
659 emit_move_insn (into_target, inter);
660
661 /* For a signed right shift, we must fill the word we are shifting
662 out of with copies of the sign bit. Otherwise it is zeroed. */
663 if (inter != 0 && binoptab != ashr_optab)
664 inter = CONST0_RTX (word_mode);
665 else if (inter != 0)
666 inter = expand_binop (word_mode, binoptab,
667 outof_input,
668 GEN_INT (BITS_PER_WORD - 1),
669 outof_target, unsignedp, next_methods);
670
671 if (inter != 0 && inter != outof_target)
672 emit_move_insn (outof_target, inter);
673 }
674 else
675 {
676 rtx carries;
677 optab reverse_unsigned_shift, unsigned_shift;
678
679 /* For a shift of less then BITS_PER_WORD, to compute the carry,
680 we must do a logical shift in the opposite direction of the
681 desired shift. */
682
683 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
684
685 /* For a shift of less than BITS_PER_WORD, to compute the word
686 shifted towards, we need to unsigned shift the orig value of
687 that word. */
688
689 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
690
691 carries = expand_binop (word_mode, reverse_unsigned_shift,
692 outof_input,
693 GEN_INT (BITS_PER_WORD - shift_count),
694 0, unsignedp, next_methods);
695
696 if (carries == 0)
697 inter = 0;
698 else
699 inter = expand_binop (word_mode, unsigned_shift, into_input,
700 op1, 0, unsignedp, next_methods);
701
702 if (inter != 0)
703 inter = expand_binop (word_mode, ior_optab, carries, inter,
704 into_target, unsignedp, next_methods);
705
706 if (inter != 0 && inter != into_target)
707 emit_move_insn (into_target, inter);
708
709 if (inter != 0)
710 inter = expand_binop (word_mode, binoptab, outof_input,
711 op1, outof_target, unsignedp, next_methods);
712
713 if (inter != 0 && inter != outof_target)
714 emit_move_insn (outof_target, inter);
715 }
716
717 insns = get_insns ();
718 end_sequence ();
719
720 if (inter != 0)
721 {
722 if (binoptab->code != UNKNOWN)
723 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
724 else
725 equiv_value = 0;
726
727 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
728 return target;
729 }
730 }
731
732 /* Synthesize double word rotates from single word shifts. */
733 if ((binoptab == rotl_optab || binoptab == rotr_optab)
734 && class == MODE_INT
735 && GET_CODE (op1) == CONST_INT
736 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
737 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
738 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
739 {
740 rtx insns, equiv_value;
741 rtx into_target, outof_target;
742 rtx into_input, outof_input;
743 rtx inter;
744 int shift_count, left_shift, outof_word;
745
746 /* If TARGET is the same as one of the operands, the REG_EQUAL note
747 won't be accurate, so use a new target. */
748 if (target == 0 || target == op0 || target == op1)
749 target = gen_reg_rtx (mode);
750
751 start_sequence ();
752
753 shift_count = INTVAL (op1);
754
755 /* OUTOF_* is the word we are shifting bits away from, and
756 INTO_* is the word that we are shifting bits towards, thus
757 they differ depending on the direction of the shift and
758 WORDS_BIG_ENDIAN. */
759
760 left_shift = (binoptab == rotl_optab);
761 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
762
763 outof_target = operand_subword (target, outof_word, 1, mode);
764 into_target = operand_subword (target, 1 - outof_word, 1, mode);
765
766 outof_input = operand_subword_force (op0, outof_word, mode);
767 into_input = operand_subword_force (op0, 1 - outof_word, mode);
768
769 if (shift_count == BITS_PER_WORD)
770 {
771 /* This is just a word swap. */
772 emit_move_insn (outof_target, into_input);
773 emit_move_insn (into_target, outof_input);
774 inter = const0_rtx;
775 }
776 else
777 {
778 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
779 rtx first_shift_count, second_shift_count;
780 optab reverse_unsigned_shift, unsigned_shift;
781
782 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
783 ? lshr_optab : ashl_optab);
784
785 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
786 ? ashl_optab : lshr_optab);
787
788 if (shift_count > BITS_PER_WORD)
789 {
790 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
791 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
792 }
793 else
794 {
795 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
796 second_shift_count = GEN_INT (shift_count);
797 }
798
799 into_temp1 = expand_binop (word_mode, unsigned_shift,
800 outof_input, first_shift_count,
801 NULL_RTX, unsignedp, next_methods);
802 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
803 into_input, second_shift_count,
804 into_target, unsignedp, next_methods);
805
806 if (into_temp1 != 0 && into_temp2 != 0)
807 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
808 into_target, unsignedp, next_methods);
809 else
810 inter = 0;
811
812 if (inter != 0 && inter != into_target)
813 emit_move_insn (into_target, inter);
814
815 outof_temp1 = expand_binop (word_mode, unsigned_shift,
816 into_input, first_shift_count,
817 NULL_RTX, unsignedp, next_methods);
818 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
819 outof_input, second_shift_count,
820 outof_target, unsignedp, next_methods);
821
822 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
823 inter = expand_binop (word_mode, ior_optab,
824 outof_temp1, outof_temp2,
825 outof_target, unsignedp, next_methods);
826
827 if (inter != 0 && inter != outof_target)
828 emit_move_insn (outof_target, inter);
829 }
830
831 insns = get_insns ();
832 end_sequence ();
833
834 if (inter != 0)
835 {
836 if (binoptab->code != UNKNOWN)
837 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
838 else
839 equiv_value = 0;
840
841 /* We can't make this a no conflict block if this is a word swap,
842 because the word swap case fails if the input and output values
843 are in the same register. */
844 if (shift_count != BITS_PER_WORD)
845 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
846 else
847 emit_insns (insns);
848
849
850 return target;
851 }
852 }
853
854 /* These can be done a word at a time by propagating carries. */
855 if ((binoptab == add_optab || binoptab == sub_optab)
856 && class == MODE_INT
857 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
858 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
859 {
860 int i;
861 rtx carry_tmp = gen_reg_rtx (word_mode);
862 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
863 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
864 rtx carry_in, carry_out;
865 rtx xop0, xop1;
866
867 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
868 value is one of those, use it. Otherwise, use 1 since it is the
869 one easiest to get. */
870 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
871 int normalizep = STORE_FLAG_VALUE;
872 #else
873 int normalizep = 1;
874 #endif
875
876 /* Prepare the operands. */
877 xop0 = force_reg (mode, op0);
878 xop1 = force_reg (mode, op1);
879
880 if (target == 0 || GET_CODE (target) != REG
881 || target == xop0 || target == xop1)
882 target = gen_reg_rtx (mode);
883
884 /* Indicate for flow that the entire target reg is being set. */
885 if (GET_CODE (target) == REG)
886 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
887
888 /* Do the actual arithmetic. */
889 for (i = 0; i < nwords; i++)
890 {
891 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
892 rtx target_piece = operand_subword (target, index, 1, mode);
893 rtx op0_piece = operand_subword_force (xop0, index, mode);
894 rtx op1_piece = operand_subword_force (xop1, index, mode);
895 rtx x;
896
897 /* Main add/subtract of the input operands. */
898 x = expand_binop (word_mode, binoptab,
899 op0_piece, op1_piece,
900 target_piece, unsignedp, next_methods);
901 if (x == 0)
902 break;
903
904 if (i + 1 < nwords)
905 {
906 /* Store carry from main add/subtract. */
907 carry_out = gen_reg_rtx (word_mode);
908 carry_out = emit_store_flag (carry_out,
909 binoptab == add_optab ? LTU : GTU,
910 x, op0_piece,
911 word_mode, 1, normalizep);
912 if (carry_out == 0)
913 break;
914 }
915
916 if (i > 0)
917 {
918 /* Add/subtract previous carry to main result. */
919 x = expand_binop (word_mode,
920 normalizep == 1 ? binoptab : otheroptab,
921 x, carry_in,
922 target_piece, 1, next_methods);
923 if (x == 0)
924 break;
925 else if (target_piece != x)
926 emit_move_insn (target_piece, x);
927
928 if (i + 1 < nwords)
929 {
930 /* THIS CODE HAS NOT BEEN TESTED. */
931 /* Get out carry from adding/subtracting carry in. */
932 carry_tmp = emit_store_flag (carry_tmp,
933 binoptab == add_optab
934 ? LTU : GTU,
935 x, carry_in,
936 word_mode, 1, normalizep);
937
938 /* Logical-ior the two poss. carry together. */
939 carry_out = expand_binop (word_mode, ior_optab,
940 carry_out, carry_tmp,
941 carry_out, 0, next_methods);
942 if (carry_out == 0)
943 break;
944 }
945 }
946
947 carry_in = carry_out;
948 }
949
950 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
951 {
952 rtx temp = emit_move_insn (target, target);
953
954 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
955 gen_rtx (binoptab->code, mode,
956 copy_rtx (xop0),
957 copy_rtx (xop1)),
958 REG_NOTES (temp));
959 return target;
960 }
961 else
962 delete_insns_since (last);
963 }
964
965 /* If we want to multiply two two-word values and have normal and widening
966 multiplies of single-word values, we can do this with three smaller
967 multiplications. Note that we do not make a REG_NO_CONFLICT block here
968 because we are not operating on one word at a time.
969
970 The multiplication proceeds as follows:
971 _______________________
972 [__op0_high_|__op0_low__]
973 _______________________
974 * [__op1_high_|__op1_low__]
975 _______________________________________________
976 _______________________
977 (1) [__op0_low__*__op1_low__]
978 _______________________
979 (2a) [__op0_low__*__op1_high_]
980 _______________________
981 (2b) [__op0_high_*__op1_low__]
982 _______________________
983 (3) [__op0_high_*__op1_high_]
984
985
986 This gives a 4-word result. Since we are only interested in the
987 lower 2 words, partial result (3) and the upper words of (2a) and
988 (2b) don't need to be calculated. Hence (2a) and (2b) can be
989 calculated using non-widening multiplication.
990
991 (1), however, needs to be calculated with an unsigned widening
992 multiplication. If this operation is not directly supported we
993 try using a signed widening multiplication and adjust the result.
994 This adjustment works as follows:
995
996 If both operands are positive then no adjustment is needed.
997
998 If the operands have different signs, for example op0_low < 0 and
999 op1_low >= 0, the instruction treats the most significant bit of
1000 op0_low as a sign bit instead of a bit with significance
1001 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1002 with 2**BITS_PER_WORD - op0_low, and two's complements the
1003 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1004 the result.
1005
1006 Similarly, if both operands are negative, we need to add
1007 (op0_low + op1_low) * 2**BITS_PER_WORD.
1008
1009 We use a trick to adjust quickly. We logically shift op0_low right
1010 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1011 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1012 logical shift exists, we do an arithmetic right shift and subtract
1013 the 0 or -1. */
1014
1015 if (binoptab == smul_optab
1016 && class == MODE_INT
1017 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1018 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1019 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1020 && ((umul_widen_optab->handlers[(int) mode].insn_code
1021 != CODE_FOR_nothing)
1022 || (smul_widen_optab->handlers[(int) mode].insn_code
1023 != CODE_FOR_nothing)))
1024 {
1025 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1026 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1027 rtx op0_high = operand_subword_force (op0, high, mode);
1028 rtx op0_low = operand_subword_force (op0, low, mode);
1029 rtx op1_high = operand_subword_force (op1, high, mode);
1030 rtx op1_low = operand_subword_force (op1, low, mode);
1031 rtx product = 0;
1032 rtx op0_xhigh;
1033 rtx op1_xhigh;
1034
1035 /* If the target is the same as one of the inputs, don't use it. This
1036 prevents problems with the REG_EQUAL note. */
1037 if (target == op0 || target == op1)
1038 target = 0;
1039
1040 /* Multiply the two lower words to get a double-word product.
1041 If unsigned widening multiplication is available, use that;
1042 otherwise use the signed form and compensate. */
1043
1044 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1045 {
1046 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1047 target, 1, OPTAB_DIRECT);
1048
1049 /* If we didn't succeed, delete everything we did so far. */
1050 if (product == 0)
1051 delete_insns_since (last);
1052 else
1053 op0_xhigh = op0_high, op1_xhigh = op1_high;
1054 }
1055
1056 if (product == 0
1057 && smul_widen_optab->handlers[(int) mode].insn_code
1058 != CODE_FOR_nothing)
1059 {
1060 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1061 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1062 target, 1, OPTAB_DIRECT);
1063 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1064 NULL_RTX, 1, next_methods);
1065 if (op0_xhigh)
1066 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1067 op0_xhigh, op0_xhigh, 0, next_methods);
1068 else
1069 {
1070 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1071 NULL_RTX, 0, next_methods);
1072 if (op0_xhigh)
1073 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1074 op0_xhigh, op0_xhigh, 0,
1075 next_methods);
1076 }
1077
1078 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1079 NULL_RTX, 1, next_methods);
1080 if (op1_xhigh)
1081 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1082 op1_xhigh, op1_xhigh, 0, next_methods);
1083 else
1084 {
1085 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1086 NULL_RTX, 0, next_methods);
1087 if (op1_xhigh)
1088 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1089 op1_xhigh, op1_xhigh, 0,
1090 next_methods);
1091 }
1092 }
1093
1094 /* If we have been able to directly compute the product of the
1095 low-order words of the operands and perform any required adjustments
1096 of the operands, we proceed by trying two more multiplications
1097 and then computing the appropriate sum.
1098
1099 We have checked above that the required addition is provided.
1100 Full-word addition will normally always succeed, especially if
1101 it is provided at all, so we don't worry about its failure. The
1102 multiplication may well fail, however, so we do handle that. */
1103
1104 if (product && op0_xhigh && op1_xhigh)
1105 {
1106 rtx product_high = operand_subword (product, high, 1, mode);
1107 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1108 NULL_RTX, 0, OPTAB_DIRECT);
1109
1110 if (temp != 0)
1111 temp = expand_binop (word_mode, add_optab, temp, product_high,
1112 product_high, 0, next_methods);
1113
1114 if (temp != 0 && temp != product_high)
1115 emit_move_insn (product_high, temp);
1116
1117 if (temp != 0)
1118 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1119 NULL_RTX, 0, OPTAB_DIRECT);
1120
1121 if (temp != 0)
1122 temp = expand_binop (word_mode, add_optab, temp,
1123 product_high, product_high,
1124 0, next_methods);
1125
1126 if (temp != 0 && temp != product_high)
1127 emit_move_insn (product_high, temp);
1128
1129 if (temp != 0)
1130 {
1131 temp = emit_move_insn (product, product);
1132 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1133 gen_rtx (MULT, mode, copy_rtx (op0),
1134 copy_rtx (op1)),
1135 REG_NOTES (temp));
1136
1137 return product;
1138 }
1139 }
1140
1141 /* If we get here, we couldn't do it for some reason even though we
1142 originally thought we could. Delete anything we've emitted in
1143 trying to do it. */
1144
1145 delete_insns_since (last);
1146 }
1147
1148 /* We need to open-code the complex type operations: '+, -, * and /' */
1149
1150 /* At this point we allow operations between two similar complex
1151 numbers, and also if one of the operands is not a complex number
1152 but rather of MODE_FLOAT or MODE_INT. However, the caller
1153 must make sure that the MODE of the non-complex operand matches
1154 the SUBMODE of the complex operand. */
1155
1156 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1157 {
1158 rtx real0 = 0, imag0 = 0;
1159 rtx real1 = 0, imag1 = 0;
1160 rtx realr, imagr, res;
1161 rtx seq;
1162 rtx equiv_value;
1163 int ok = 0;
1164
1165 /* Find the correct mode for the real and imaginary parts */
1166 enum machine_mode submode
1167 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1168 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1169 0);
1170
1171 if (submode == BLKmode)
1172 abort ();
1173
1174 if (! target)
1175 target = gen_reg_rtx (mode);
1176
1177 start_sequence ();
1178
1179 realr = gen_realpart (submode, target);
1180 imagr = gen_imagpart (submode, target);
1181
1182 if (GET_MODE (op0) == mode)
1183 {
1184 real0 = gen_realpart (submode, op0);
1185 imag0 = gen_imagpart (submode, op0);
1186 }
1187 else
1188 real0 = op0;
1189
1190 if (GET_MODE (op1) == mode)
1191 {
1192 real1 = gen_realpart (submode, op1);
1193 imag1 = gen_imagpart (submode, op1);
1194 }
1195 else
1196 real1 = op1;
1197
1198 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1199 abort ();
1200
1201 switch (binoptab->code)
1202 {
1203 case PLUS:
1204 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1205 case MINUS:
1206 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1207 res = expand_binop (submode, binoptab, real0, real1,
1208 realr, unsignedp, methods);
1209
1210 if (res == 0)
1211 break;
1212 else if (res != realr)
1213 emit_move_insn (realr, res);
1214
1215 if (imag0 && imag1)
1216 res = expand_binop (submode, binoptab, imag0, imag1,
1217 imagr, unsignedp, methods);
1218 else if (imag0)
1219 res = imag0;
1220 else if (binoptab->code == MINUS)
1221 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1222 else
1223 res = imag1;
1224
1225 if (res == 0)
1226 break;
1227 else if (res != imagr)
1228 emit_move_insn (imagr, res);
1229
1230 ok = 1;
1231 break;
1232
1233 case MULT:
1234 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1235
1236 if (imag0 && imag1)
1237 {
1238 rtx temp1, temp2;
1239
1240 /* Don't fetch these from memory more than once. */
1241 real0 = force_reg (submode, real0);
1242 real1 = force_reg (submode, real1);
1243 imag0 = force_reg (submode, imag0);
1244 imag1 = force_reg (submode, imag1);
1245
1246 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1247 unsignedp, methods);
1248
1249 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1250 unsignedp, methods);
1251
1252 if (temp1 == 0 || temp2 == 0)
1253 break;
1254
1255 res = expand_binop (submode, sub_optab, temp1, temp2,
1256 realr, unsignedp, methods);
1257
1258 if (res == 0)
1259 break;
1260 else if (res != realr)
1261 emit_move_insn (realr, res);
1262
1263 temp1 = expand_binop (submode, binoptab, real0, imag1,
1264 NULL_RTX, unsignedp, methods);
1265
1266 temp2 = expand_binop (submode, binoptab, real1, imag0,
1267 NULL_RTX, unsignedp, methods);
1268
1269 if (temp1 == 0 || temp2 == 0)
1270 break;
1271
1272 res = expand_binop (submode, add_optab, temp1, temp2,
1273 imagr, unsignedp, methods);
1274
1275 if (res == 0)
1276 break;
1277 else if (res != imagr)
1278 emit_move_insn (imagr, res);
1279
1280 ok = 1;
1281 }
1282 else
1283 {
1284 /* Don't fetch these from memory more than once. */
1285 real0 = force_reg (submode, real0);
1286 real1 = force_reg (submode, real1);
1287
1288 res = expand_binop (submode, binoptab, real0, real1,
1289 realr, unsignedp, methods);
1290 if (res == 0)
1291 break;
1292 else if (res != realr)
1293 emit_move_insn (realr, res);
1294
1295 if (imag0 != 0)
1296 res = expand_binop (submode, binoptab,
1297 real1, imag0, imagr, unsignedp, methods);
1298 else
1299 res = expand_binop (submode, binoptab,
1300 real0, imag1, imagr, unsignedp, methods);
1301
1302 if (res == 0)
1303 break;
1304 else if (res != imagr)
1305 emit_move_insn (imagr, res);
1306
1307 ok = 1;
1308 }
1309 break;
1310
1311 case DIV:
1312 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1313
1314 if (imag1 == 0)
1315 {
1316 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1317
1318 /* Don't fetch these from memory more than once. */
1319 real1 = force_reg (submode, real1);
1320
1321 /* Simply divide the real and imaginary parts by `c' */
1322 if (class == MODE_COMPLEX_FLOAT)
1323 res = expand_binop (submode, binoptab, real0, real1,
1324 realr, unsignedp, methods);
1325 else
1326 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1327 real0, real1, realr, unsignedp);
1328
1329 if (res == 0)
1330 break;
1331 else if (res != realr)
1332 emit_move_insn (realr, res);
1333
1334 if (class == MODE_COMPLEX_FLOAT)
1335 res = expand_binop (submode, binoptab, imag0, real1,
1336 imagr, unsignedp, methods);
1337 else
1338 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1339 imag0, real1, imagr, unsignedp);
1340
1341 if (res == 0)
1342 break;
1343 else if (res != imagr)
1344 emit_move_insn (imagr, res);
1345
1346 ok = 1;
1347 }
1348 else
1349 {
1350 /* Divisor is of complex type:
1351 X/(a+ib) */
1352 rtx divisor;
1353 rtx real_t, imag_t;
1354 rtx lhs, rhs;
1355 rtx temp1, temp2;
1356
1357 /* Don't fetch these from memory more than once. */
1358 real0 = force_reg (submode, real0);
1359 real1 = force_reg (submode, real1);
1360
1361 if (imag0 != 0)
1362 imag0 = force_reg (submode, imag0);
1363
1364 imag1 = force_reg (submode, imag1);
1365
1366 /* Divisor: c*c + d*d */
1367 temp1 = expand_binop (submode, smul_optab, real1, real1,
1368 NULL_RTX, unsignedp, methods);
1369
1370 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1371 NULL_RTX, unsignedp, methods);
1372
1373 if (temp1 == 0 || temp2 == 0)
1374 break;
1375
1376 divisor = expand_binop (submode, add_optab, temp1, temp2,
1377 NULL_RTX, unsignedp, methods);
1378 if (divisor == 0)
1379 break;
1380
1381 if (imag0 == 0)
1382 {
1383 /* ((a)(c-id))/divisor */
1384 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1385
1386 /* Calculate the dividend */
1387 real_t = expand_binop (submode, smul_optab, real0, real1,
1388 NULL_RTX, unsignedp, methods);
1389
1390 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1391 NULL_RTX, unsignedp, methods);
1392
1393 if (real_t == 0 || imag_t == 0)
1394 break;
1395
1396 imag_t = expand_unop (submode, neg_optab, imag_t,
1397 NULL_RTX, unsignedp);
1398 }
1399 else
1400 {
1401 /* ((a+ib)(c-id))/divider */
1402 /* Calculate the dividend */
1403 temp1 = expand_binop (submode, smul_optab, real0, real1,
1404 NULL_RTX, unsignedp, methods);
1405
1406 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1407 NULL_RTX, unsignedp, methods);
1408
1409 if (temp1 == 0 || temp2 == 0)
1410 break;
1411
1412 real_t = expand_binop (submode, add_optab, temp1, temp2,
1413 NULL_RTX, unsignedp, methods);
1414
1415 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1416 NULL_RTX, unsignedp, methods);
1417
1418 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1419 NULL_RTX, unsignedp, methods);
1420
1421 if (temp1 == 0 || temp2 == 0)
1422 break;
1423
1424 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1425 NULL_RTX, unsignedp, methods);
1426
1427 if (real_t == 0 || imag_t == 0)
1428 break;
1429 }
1430
1431 if (class == MODE_COMPLEX_FLOAT)
1432 res = expand_binop (submode, binoptab, real_t, divisor,
1433 realr, unsignedp, methods);
1434 else
1435 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1436 real_t, divisor, realr, unsignedp);
1437
1438 if (res == 0)
1439 break;
1440 else if (res != realr)
1441 emit_move_insn (realr, res);
1442
1443 if (class == MODE_COMPLEX_FLOAT)
1444 res = expand_binop (submode, binoptab, imag_t, divisor,
1445 imagr, unsignedp, methods);
1446 else
1447 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1448 imag_t, divisor, imagr, unsignedp);
1449
1450 if (res == 0)
1451 break;
1452 else if (res != imagr)
1453 emit_move_insn (imagr, res);
1454
1455 ok = 1;
1456 }
1457 break;
1458
1459 default:
1460 abort ();
1461 }
1462
1463 seq = get_insns ();
1464 end_sequence ();
1465
1466 if (ok)
1467 {
1468 if (binoptab->code != UNKNOWN)
1469 equiv_value
1470 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1471 else
1472 equiv_value = 0;
1473
1474 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1475
1476 return target;
1477 }
1478 }
1479
1480 /* It can't be open-coded in this mode.
1481 Use a library call if one is available and caller says that's ok. */
1482
1483 if (binoptab->handlers[(int) mode].libfunc
1484 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1485 {
1486 rtx insns;
1487 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1488 rtx op1x = op1;
1489 enum machine_mode op1_mode = mode;
1490 rtx value;
1491
1492 start_sequence ();
1493
1494 if (shift_op)
1495 {
1496 op1_mode = word_mode;
1497 /* Specify unsigned here,
1498 since negative shift counts are meaningless. */
1499 op1x = convert_to_mode (word_mode, op1, 1);
1500 }
1501
1502 if (GET_MODE (op0) != mode)
1503 op0 = convert_to_mode (mode, op0, unsignedp);
1504
1505 /* Pass 1 for NO_QUEUE so we don't lose any increments
1506 if the libcall is cse'd or moved. */
1507 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1508 NULL_RTX, 1, mode, 2,
1509 op0, mode, op1x, op1_mode);
1510
1511 insns = get_insns ();
1512 end_sequence ();
1513
1514 target = gen_reg_rtx (mode);
1515 emit_libcall_block (insns, target, value,
1516 gen_rtx (binoptab->code, mode, op0, op1));
1517
1518 return target;
1519 }
1520
1521 delete_insns_since (last);
1522
1523 /* It can't be done in this mode. Can we do it in a wider mode? */
1524
1525 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1526 || methods == OPTAB_MUST_WIDEN))
1527 {
1528 /* Caller says, don't even try. */
1529 delete_insns_since (entry_last);
1530 return 0;
1531 }
1532
1533 /* Compute the value of METHODS to pass to recursive calls.
1534 Don't allow widening to be tried recursively. */
1535
1536 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1537
1538 /* Look for a wider mode of the same class for which it appears we can do
1539 the operation. */
1540
1541 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1542 {
1543 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1544 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1545 {
1546 if ((binoptab->handlers[(int) wider_mode].insn_code
1547 != CODE_FOR_nothing)
1548 || (methods == OPTAB_LIB
1549 && binoptab->handlers[(int) wider_mode].libfunc))
1550 {
1551 rtx xop0 = op0, xop1 = op1;
1552 int no_extend = 0;
1553
1554 /* For certain integer operations, we need not actually extend
1555 the narrow operands, as long as we will truncate
1556 the results to the same narrowness. */
1557
1558 if ((binoptab == ior_optab || binoptab == and_optab
1559 || binoptab == xor_optab
1560 || binoptab == add_optab || binoptab == sub_optab
1561 || binoptab == smul_optab || binoptab == ashl_optab)
1562 && class == MODE_INT)
1563 no_extend = 1;
1564
1565 xop0 = widen_operand (xop0, wider_mode, mode,
1566 unsignedp, no_extend);
1567
1568 /* The second operand of a shift must always be extended. */
1569 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1570 no_extend && binoptab != ashl_optab);
1571
1572 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1573 unsignedp, methods);
1574 if (temp)
1575 {
1576 if (class != MODE_INT)
1577 {
1578 if (target == 0)
1579 target = gen_reg_rtx (mode);
1580 convert_move (target, temp, 0);
1581 return target;
1582 }
1583 else
1584 return gen_lowpart (mode, temp);
1585 }
1586 else
1587 delete_insns_since (last);
1588 }
1589 }
1590 }
1591
1592 delete_insns_since (entry_last);
1593 return 0;
1594 }
1595 \f
1596 /* Expand a binary operator which has both signed and unsigned forms.
1597 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1598 signed operations.
1599
1600 If we widen unsigned operands, we may use a signed wider operation instead
1601 of an unsigned wider operation, since the result would be the same. */
1602
1603 rtx
1604 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1605 enum machine_mode mode;
1606 optab uoptab, soptab;
1607 rtx op0, op1, target;
1608 int unsignedp;
1609 enum optab_methods methods;
1610 {
1611 register rtx temp;
1612 optab direct_optab = unsignedp ? uoptab : soptab;
1613 struct optab wide_soptab;
1614
1615 /* Do it without widening, if possible. */
1616 temp = expand_binop (mode, direct_optab, op0, op1, target,
1617 unsignedp, OPTAB_DIRECT);
1618 if (temp || methods == OPTAB_DIRECT)
1619 return temp;
1620
1621 /* Try widening to a signed int. Make a fake signed optab that
1622 hides any signed insn for direct use. */
1623 wide_soptab = *soptab;
1624 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1625 wide_soptab.handlers[(int) mode].libfunc = 0;
1626
1627 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1628 unsignedp, OPTAB_WIDEN);
1629
1630 /* For unsigned operands, try widening to an unsigned int. */
1631 if (temp == 0 && unsignedp)
1632 temp = expand_binop (mode, uoptab, op0, op1, target,
1633 unsignedp, OPTAB_WIDEN);
1634 if (temp || methods == OPTAB_WIDEN)
1635 return temp;
1636
1637 /* Use the right width lib call if that exists. */
1638 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1639 if (temp || methods == OPTAB_LIB)
1640 return temp;
1641
1642 /* Must widen and use a lib call, use either signed or unsigned. */
1643 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1644 unsignedp, methods);
1645 if (temp != 0)
1646 return temp;
1647 if (unsignedp)
1648 return expand_binop (mode, uoptab, op0, op1, target,
1649 unsignedp, methods);
1650 return 0;
1651 }
1652 \f
1653 /* Generate code to perform an operation specified by BINOPTAB
1654 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1655 We assume that the order of the operands for the instruction
1656 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1657 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1658
1659 Either TARG0 or TARG1 may be zero, but what that means is that
1660 that result is not actually wanted. We will generate it into
1661 a dummy pseudo-reg and discard it. They may not both be zero.
1662
1663 Returns 1 if this operation can be performed; 0 if not. */
1664
1665 int
1666 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1667 optab binoptab;
1668 rtx op0, op1;
1669 rtx targ0, targ1;
1670 int unsignedp;
1671 {
1672 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1673 enum mode_class class;
1674 enum machine_mode wider_mode;
1675 rtx entry_last = get_last_insn ();
1676 rtx last;
1677
1678 class = GET_MODE_CLASS (mode);
1679
1680 op0 = protect_from_queue (op0, 0);
1681 op1 = protect_from_queue (op1, 0);
1682
1683 if (flag_force_mem)
1684 {
1685 op0 = force_not_mem (op0);
1686 op1 = force_not_mem (op1);
1687 }
1688
1689 /* If we are inside an appropriately-short loop and one operand is an
1690 expensive constant, force it into a register. */
1691 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1692 && rtx_cost (op0, binoptab->code) > 2)
1693 op0 = force_reg (mode, op0);
1694
1695 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1696 && rtx_cost (op1, binoptab->code) > 2)
1697 op1 = force_reg (mode, op1);
1698
1699 if (targ0)
1700 targ0 = protect_from_queue (targ0, 1);
1701 else
1702 targ0 = gen_reg_rtx (mode);
1703 if (targ1)
1704 targ1 = protect_from_queue (targ1, 1);
1705 else
1706 targ1 = gen_reg_rtx (mode);
1707
1708 /* Record where to go back to if we fail. */
1709 last = get_last_insn ();
1710
1711 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1712 {
1713 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1714 enum machine_mode mode0 = insn_operand_mode[icode][1];
1715 enum machine_mode mode1 = insn_operand_mode[icode][2];
1716 rtx pat;
1717 rtx xop0 = op0, xop1 = op1;
1718
1719 /* In case this insn wants input operands in modes different from the
1720 result, convert the operands. */
1721 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1722 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1723
1724 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1725 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1726
1727 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1728 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1729 xop0 = copy_to_mode_reg (mode0, xop0);
1730
1731 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1732 xop1 = copy_to_mode_reg (mode1, xop1);
1733
1734 /* We could handle this, but we should always be called with a pseudo
1735 for our targets and all insns should take them as outputs. */
1736 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1737 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1738 abort ();
1739
1740 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1741 if (pat)
1742 {
1743 emit_insn (pat);
1744 return 1;
1745 }
1746 else
1747 delete_insns_since (last);
1748 }
1749
1750 /* It can't be done in this mode. Can we do it in a wider mode? */
1751
1752 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1753 {
1754 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1755 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1756 {
1757 if (binoptab->handlers[(int) wider_mode].insn_code
1758 != CODE_FOR_nothing)
1759 {
1760 register rtx t0 = gen_reg_rtx (wider_mode);
1761 register rtx t1 = gen_reg_rtx (wider_mode);
1762
1763 if (expand_twoval_binop (binoptab,
1764 convert_modes (wider_mode, mode, op0,
1765 unsignedp),
1766 convert_modes (wider_mode, mode, op1,
1767 unsignedp),
1768 t0, t1, unsignedp))
1769 {
1770 convert_move (targ0, t0, unsignedp);
1771 convert_move (targ1, t1, unsignedp);
1772 return 1;
1773 }
1774 else
1775 delete_insns_since (last);
1776 }
1777 }
1778 }
1779
1780 delete_insns_since (entry_last);
1781 return 0;
1782 }
1783 \f
1784 /* Generate code to perform an operation specified by UNOPTAB
1785 on operand OP0, with result having machine-mode MODE.
1786
1787 UNSIGNEDP is for the case where we have to widen the operands
1788 to perform the operation. It says to use zero-extension.
1789
1790 If TARGET is nonzero, the value
1791 is generated there, if it is convenient to do so.
1792 In all cases an rtx is returned for the locus of the value;
1793 this may or may not be TARGET. */
1794
1795 rtx
1796 expand_unop (mode, unoptab, op0, target, unsignedp)
1797 enum machine_mode mode;
1798 optab unoptab;
1799 rtx op0;
1800 rtx target;
1801 int unsignedp;
1802 {
1803 enum mode_class class;
1804 enum machine_mode wider_mode;
1805 register rtx temp;
1806 rtx last = get_last_insn ();
1807 rtx pat;
1808
1809 class = GET_MODE_CLASS (mode);
1810
1811 op0 = protect_from_queue (op0, 0);
1812
1813 if (flag_force_mem)
1814 {
1815 op0 = force_not_mem (op0);
1816 }
1817
1818 if (target)
1819 target = protect_from_queue (target, 1);
1820
1821 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1822 {
1823 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1824 enum machine_mode mode0 = insn_operand_mode[icode][1];
1825 rtx xop0 = op0;
1826
1827 if (target)
1828 temp = target;
1829 else
1830 temp = gen_reg_rtx (mode);
1831
1832 if (GET_MODE (xop0) != VOIDmode
1833 && GET_MODE (xop0) != mode0)
1834 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1835
1836 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1837
1838 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1839 xop0 = copy_to_mode_reg (mode0, xop0);
1840
1841 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1842 temp = gen_reg_rtx (mode);
1843
1844 pat = GEN_FCN (icode) (temp, xop0);
1845 if (pat)
1846 {
1847 if (GET_CODE (pat) == SEQUENCE
1848 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1849 {
1850 delete_insns_since (last);
1851 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1852 }
1853
1854 emit_insn (pat);
1855
1856 return temp;
1857 }
1858 else
1859 delete_insns_since (last);
1860 }
1861
1862 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1863
1864 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1865 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1866 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1867 {
1868 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1869 {
1870 rtx xop0 = op0;
1871
1872 /* For certain operations, we need not actually extend
1873 the narrow operand, as long as we will truncate the
1874 results to the same narrowness. */
1875
1876 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1877 (unoptab == neg_optab
1878 || unoptab == one_cmpl_optab)
1879 && class == MODE_INT);
1880
1881 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1882 unsignedp);
1883
1884 if (temp)
1885 {
1886 if (class != MODE_INT)
1887 {
1888 if (target == 0)
1889 target = gen_reg_rtx (mode);
1890 convert_move (target, temp, 0);
1891 return target;
1892 }
1893 else
1894 return gen_lowpart (mode, temp);
1895 }
1896 else
1897 delete_insns_since (last);
1898 }
1899 }
1900
1901 /* These can be done a word at a time. */
1902 if (unoptab == one_cmpl_optab
1903 && class == MODE_INT
1904 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1905 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1906 {
1907 int i;
1908 rtx insns;
1909
1910 if (target == 0 || target == op0)
1911 target = gen_reg_rtx (mode);
1912
1913 start_sequence ();
1914
1915 /* Do the actual arithmetic. */
1916 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1917 {
1918 rtx target_piece = operand_subword (target, i, 1, mode);
1919 rtx x = expand_unop (word_mode, unoptab,
1920 operand_subword_force (op0, i, mode),
1921 target_piece, unsignedp);
1922 if (target_piece != x)
1923 emit_move_insn (target_piece, x);
1924 }
1925
1926 insns = get_insns ();
1927 end_sequence ();
1928
1929 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1930 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1931 return target;
1932 }
1933
1934 /* Open-code the complex negation operation. */
1935 else if (unoptab == neg_optab
1936 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1937 {
1938 rtx target_piece;
1939 rtx x;
1940 rtx seq;
1941
1942 /* Find the correct mode for the real and imaginary parts */
1943 enum machine_mode submode
1944 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1945 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1946 0);
1947
1948 if (submode == BLKmode)
1949 abort ();
1950
1951 if (target == 0)
1952 target = gen_reg_rtx (mode);
1953
1954 start_sequence ();
1955
1956 target_piece = gen_imagpart (submode, target);
1957 x = expand_unop (submode, unoptab,
1958 gen_imagpart (submode, op0),
1959 target_piece, unsignedp);
1960 if (target_piece != x)
1961 emit_move_insn (target_piece, x);
1962
1963 target_piece = gen_realpart (submode, target);
1964 x = expand_unop (submode, unoptab,
1965 gen_realpart (submode, op0),
1966 target_piece, unsignedp);
1967 if (target_piece != x)
1968 emit_move_insn (target_piece, x);
1969
1970 seq = get_insns ();
1971 end_sequence ();
1972
1973 emit_no_conflict_block (seq, target, op0, 0,
1974 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1975 return target;
1976 }
1977
1978 /* Now try a library call in this mode. */
1979 if (unoptab->handlers[(int) mode].libfunc)
1980 {
1981 rtx insns;
1982 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1983 rtx value;
1984
1985 start_sequence ();
1986
1987 /* Pass 1 for NO_QUEUE so we don't lose any increments
1988 if the libcall is cse'd or moved. */
1989 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
1990 NULL_RTX, 1, mode, 1, op0, mode);
1991 insns = get_insns ();
1992 end_sequence ();
1993
1994 target = gen_reg_rtx (mode);
1995 emit_libcall_block (insns, target, value,
1996 gen_rtx (unoptab->code, mode, op0));
1997
1998 return target;
1999 }
2000
2001 /* It can't be done in this mode. Can we do it in a wider mode? */
2002
2003 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2004 {
2005 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2006 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2007 {
2008 if ((unoptab->handlers[(int) wider_mode].insn_code
2009 != CODE_FOR_nothing)
2010 || unoptab->handlers[(int) wider_mode].libfunc)
2011 {
2012 rtx xop0 = op0;
2013
2014 /* For certain operations, we need not actually extend
2015 the narrow operand, as long as we will truncate the
2016 results to the same narrowness. */
2017
2018 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2019 (unoptab == neg_optab
2020 || unoptab == one_cmpl_optab)
2021 && class == MODE_INT);
2022
2023 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2024 unsignedp);
2025
2026 if (temp)
2027 {
2028 if (class != MODE_INT)
2029 {
2030 if (target == 0)
2031 target = gen_reg_rtx (mode);
2032 convert_move (target, temp, 0);
2033 return target;
2034 }
2035 else
2036 return gen_lowpart (mode, temp);
2037 }
2038 else
2039 delete_insns_since (last);
2040 }
2041 }
2042 }
2043
2044 /* If there is no negate operation, try doing a subtract from zero.
2045 The US Software GOFAST library needs this. */
2046 if (unoptab == neg_optab)
2047 {
2048 rtx temp;
2049 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2050 target, unsignedp, OPTAB_LIB_WIDEN);
2051 if (temp)
2052 return temp;
2053 }
2054
2055 return 0;
2056 }
2057 \f
2058 /* Emit code to compute the absolute value of OP0, with result to
2059 TARGET if convenient. (TARGET may be 0.) The return value says
2060 where the result actually is to be found.
2061
2062 MODE is the mode of the operand; the mode of the result is
2063 different but can be deduced from MODE.
2064
2065 UNSIGNEDP is relevant if extension is needed. */
2066
2067 rtx
2068 expand_abs (mode, op0, target, unsignedp, safe)
2069 enum machine_mode mode;
2070 rtx op0;
2071 rtx target;
2072 int unsignedp;
2073 int safe;
2074 {
2075 rtx temp, op1;
2076
2077 /* First try to do it with a special abs instruction. */
2078 temp = expand_unop (mode, abs_optab, op0, target, 0);
2079 if (temp != 0)
2080 return temp;
2081
2082 /* If this machine has expensive jumps, we can do integer absolute
2083 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2084 where W is the width of MODE. */
2085
2086 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2087 {
2088 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2089 size_int (GET_MODE_BITSIZE (mode) - 1),
2090 NULL_RTX, 0);
2091
2092 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2093 OPTAB_LIB_WIDEN);
2094 if (temp != 0)
2095 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2096 OPTAB_LIB_WIDEN);
2097
2098 if (temp != 0)
2099 return temp;
2100 }
2101
2102 /* If that does not win, use conditional jump and negate. */
2103 op1 = gen_label_rtx ();
2104 if (target == 0 || ! safe
2105 || GET_MODE (target) != mode
2106 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2107 || (GET_CODE (target) == REG
2108 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2109 target = gen_reg_rtx (mode);
2110
2111 emit_move_insn (target, op0);
2112 NO_DEFER_POP;
2113
2114 /* If this mode is an integer too wide to compare properly,
2115 compare word by word. Rely on CSE to optimize constant cases. */
2116 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2117 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2118 NULL_RTX, op1);
2119 else
2120 {
2121 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2122 NULL_RTX, 0);
2123 if (temp == const1_rtx)
2124 return target;
2125 else if (temp != const0_rtx)
2126 {
2127 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2128 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2129 else
2130 abort ();
2131 }
2132 }
2133
2134 op0 = expand_unop (mode, neg_optab, target, target, 0);
2135 if (op0 != target)
2136 emit_move_insn (target, op0);
2137 emit_label (op1);
2138 OK_DEFER_POP;
2139 return target;
2140 }
2141 \f
2142 /* Emit code to compute the absolute value of OP0, with result to
2143 TARGET if convenient. (TARGET may be 0.) The return value says
2144 where the result actually is to be found.
2145
2146 MODE is the mode of the operand; the mode of the result is
2147 different but can be deduced from MODE.
2148
2149 UNSIGNEDP is relevant for complex integer modes. */
2150
2151 rtx
2152 expand_complex_abs (mode, op0, target, unsignedp)
2153 enum machine_mode mode;
2154 rtx op0;
2155 rtx target;
2156 int unsignedp;
2157 {
2158 enum mode_class class = GET_MODE_CLASS (mode);
2159 enum machine_mode wider_mode;
2160 register rtx temp;
2161 rtx entry_last = get_last_insn ();
2162 rtx last;
2163 rtx pat;
2164
2165 /* Find the correct mode for the real and imaginary parts. */
2166 enum machine_mode submode
2167 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2168 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2169 0);
2170
2171 if (submode == BLKmode)
2172 abort ();
2173
2174 op0 = protect_from_queue (op0, 0);
2175
2176 if (flag_force_mem)
2177 {
2178 op0 = force_not_mem (op0);
2179 }
2180
2181 last = get_last_insn ();
2182
2183 if (target)
2184 target = protect_from_queue (target, 1);
2185
2186 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2187 {
2188 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2189 enum machine_mode mode0 = insn_operand_mode[icode][1];
2190 rtx xop0 = op0;
2191
2192 if (target)
2193 temp = target;
2194 else
2195 temp = gen_reg_rtx (submode);
2196
2197 if (GET_MODE (xop0) != VOIDmode
2198 && GET_MODE (xop0) != mode0)
2199 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2200
2201 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2202
2203 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2204 xop0 = copy_to_mode_reg (mode0, xop0);
2205
2206 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2207 temp = gen_reg_rtx (submode);
2208
2209 pat = GEN_FCN (icode) (temp, xop0);
2210 if (pat)
2211 {
2212 if (GET_CODE (pat) == SEQUENCE
2213 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2214 {
2215 delete_insns_since (last);
2216 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2217 }
2218
2219 emit_insn (pat);
2220
2221 return temp;
2222 }
2223 else
2224 delete_insns_since (last);
2225 }
2226
2227 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2228
2229 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2230 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2231 {
2232 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2233 {
2234 rtx xop0 = op0;
2235
2236 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2237 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2238
2239 if (temp)
2240 {
2241 if (class != MODE_COMPLEX_INT)
2242 {
2243 if (target == 0)
2244 target = gen_reg_rtx (submode);
2245 convert_move (target, temp, 0);
2246 return target;
2247 }
2248 else
2249 return gen_lowpart (submode, temp);
2250 }
2251 else
2252 delete_insns_since (last);
2253 }
2254 }
2255
2256 /* Open-code the complex absolute-value operation
2257 if we can open-code sqrt. Otherwise it's not worth while. */
2258 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2259 {
2260 rtx real, imag, total;
2261
2262 real = gen_realpart (submode, op0);
2263 imag = gen_imagpart (submode, op0);
2264
2265 /* Square both parts. */
2266 real = expand_mult (submode, real, real, NULL_RTX, 0);
2267 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2268
2269 /* Sum the parts. */
2270 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2271 0, OPTAB_LIB_WIDEN);
2272
2273 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2274 target = expand_unop (submode, sqrt_optab, total, target, 0);
2275 if (target == 0)
2276 delete_insns_since (last);
2277 else
2278 return target;
2279 }
2280
2281 /* Now try a library call in this mode. */
2282 if (abs_optab->handlers[(int) mode].libfunc)
2283 {
2284 rtx insns;
2285 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2286 rtx value;
2287
2288 start_sequence ();
2289
2290 /* Pass 1 for NO_QUEUE so we don't lose any increments
2291 if the libcall is cse'd or moved. */
2292 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2293 NULL_RTX, 1, submode, 1, op0, mode);
2294 insns = get_insns ();
2295 end_sequence ();
2296
2297 target = gen_reg_rtx (submode);
2298 emit_libcall_block (insns, target, value,
2299 gen_rtx (abs_optab->code, mode, op0));
2300
2301 return target;
2302 }
2303
2304 /* It can't be done in this mode. Can we do it in a wider mode? */
2305
2306 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2307 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2308 {
2309 if ((abs_optab->handlers[(int) wider_mode].insn_code
2310 != CODE_FOR_nothing)
2311 || abs_optab->handlers[(int) wider_mode].libfunc)
2312 {
2313 rtx xop0 = op0;
2314
2315 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2316
2317 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2318
2319 if (temp)
2320 {
2321 if (class != MODE_COMPLEX_INT)
2322 {
2323 if (target == 0)
2324 target = gen_reg_rtx (submode);
2325 convert_move (target, temp, 0);
2326 return target;
2327 }
2328 else
2329 return gen_lowpart (submode, temp);
2330 }
2331 else
2332 delete_insns_since (last);
2333 }
2334 }
2335
2336 delete_insns_since (entry_last);
2337 return 0;
2338 }
2339 \f
2340 /* Generate an instruction whose insn-code is INSN_CODE,
2341 with two operands: an output TARGET and an input OP0.
2342 TARGET *must* be nonzero, and the output is always stored there.
2343 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2344 the value that is stored into TARGET. */
2345
2346 void
2347 emit_unop_insn (icode, target, op0, code)
2348 int icode;
2349 rtx target;
2350 rtx op0;
2351 enum rtx_code code;
2352 {
2353 register rtx temp;
2354 enum machine_mode mode0 = insn_operand_mode[icode][1];
2355 rtx pat;
2356
2357 temp = target = protect_from_queue (target, 1);
2358
2359 op0 = protect_from_queue (op0, 0);
2360
2361 if (flag_force_mem)
2362 op0 = force_not_mem (op0);
2363
2364 /* Now, if insn does not accept our operands, put them into pseudos. */
2365
2366 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2367 op0 = copy_to_mode_reg (mode0, op0);
2368
2369 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2370 || (flag_force_mem && GET_CODE (temp) == MEM))
2371 temp = gen_reg_rtx (GET_MODE (temp));
2372
2373 pat = GEN_FCN (icode) (temp, op0);
2374
2375 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2376 add_equal_note (pat, temp, code, op0, NULL_RTX);
2377
2378 emit_insn (pat);
2379
2380 if (temp != target)
2381 emit_move_insn (target, temp);
2382 }
2383 \f
2384 /* Emit code to perform a series of operations on a multi-word quantity, one
2385 word at a time.
2386
2387 Such a block is preceded by a CLOBBER of the output, consists of multiple
2388 insns, each setting one word of the output, and followed by a SET copying
2389 the output to itself.
2390
2391 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2392 note indicating that it doesn't conflict with the (also multi-word)
2393 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2394 notes.
2395
2396 INSNS is a block of code generated to perform the operation, not including
2397 the CLOBBER and final copy. All insns that compute intermediate values
2398 are first emitted, followed by the block as described above. Only
2399 INSNs are allowed in the block; no library calls or jumps may be
2400 present.
2401
2402 TARGET, OP0, and OP1 are the output and inputs of the operations,
2403 respectively. OP1 may be zero for a unary operation.
2404
2405 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2406 on the last insn.
2407
2408 If TARGET is not a register, INSNS is simply emitted with no special
2409 processing.
2410
2411 The final insn emitted is returned. */
2412
2413 rtx
2414 emit_no_conflict_block (insns, target, op0, op1, equiv)
2415 rtx insns;
2416 rtx target;
2417 rtx op0, op1;
2418 rtx equiv;
2419 {
2420 rtx prev, next, first, last, insn;
2421
2422 if (GET_CODE (target) != REG || reload_in_progress)
2423 return emit_insns (insns);
2424
2425 /* First emit all insns that do not store into words of the output and remove
2426 these from the list. */
2427 for (insn = insns; insn; insn = next)
2428 {
2429 rtx set = 0;
2430 int i;
2431
2432 next = NEXT_INSN (insn);
2433
2434 if (GET_CODE (insn) != INSN)
2435 abort ();
2436
2437 if (GET_CODE (PATTERN (insn)) == SET)
2438 set = PATTERN (insn);
2439 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2440 {
2441 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2442 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2443 {
2444 set = XVECEXP (PATTERN (insn), 0, i);
2445 break;
2446 }
2447 }
2448
2449 if (set == 0)
2450 abort ();
2451
2452 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2453 {
2454 if (PREV_INSN (insn))
2455 NEXT_INSN (PREV_INSN (insn)) = next;
2456 else
2457 insns = next;
2458
2459 if (next)
2460 PREV_INSN (next) = PREV_INSN (insn);
2461
2462 add_insn (insn);
2463 }
2464 }
2465
2466 prev = get_last_insn ();
2467
2468 /* Now write the CLOBBER of the output, followed by the setting of each
2469 of the words, followed by the final copy. */
2470 if (target != op0 && target != op1)
2471 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2472
2473 for (insn = insns; insn; insn = next)
2474 {
2475 next = NEXT_INSN (insn);
2476 add_insn (insn);
2477
2478 if (op1 && GET_CODE (op1) == REG)
2479 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2480 REG_NOTES (insn));
2481
2482 if (op0 && GET_CODE (op0) == REG)
2483 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2484 REG_NOTES (insn));
2485 }
2486
2487 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2488 != CODE_FOR_nothing)
2489 {
2490 last = emit_move_insn (target, target);
2491 if (equiv)
2492 REG_NOTES (last)
2493 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2494 }
2495 else
2496 last = get_last_insn ();
2497
2498 if (prev == 0)
2499 first = get_insns ();
2500 else
2501 first = NEXT_INSN (prev);
2502
2503 /* Encapsulate the block so it gets manipulated as a unit. */
2504 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2505 REG_NOTES (first));
2506 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2507
2508 return last;
2509 }
2510 \f
2511 /* Emit code to make a call to a constant function or a library call.
2512
2513 INSNS is a list containing all insns emitted in the call.
2514 These insns leave the result in RESULT. Our block is to copy RESULT
2515 to TARGET, which is logically equivalent to EQUIV.
2516
2517 We first emit any insns that set a pseudo on the assumption that these are
2518 loading constants into registers; doing so allows them to be safely cse'ed
2519 between blocks. Then we emit all the other insns in the block, followed by
2520 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2521 note with an operand of EQUIV.
2522
2523 Moving assignments to pseudos outside of the block is done to improve
2524 the generated code, but is not required to generate correct code,
2525 hence being unable to move an assignment is not grounds for not making
2526 a libcall block. There are two reasons why it is safe to leave these
2527 insns inside the block: First, we know that these pseudos cannot be
2528 used in generated RTL outside the block since they are created for
2529 temporary purposes within the block. Second, CSE will not record the
2530 values of anything set inside a libcall block, so we know they must
2531 be dead at the end of the block.
2532
2533 Except for the first group of insns (the ones setting pseudos), the
2534 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2535
2536 void
2537 emit_libcall_block (insns, target, result, equiv)
2538 rtx insns;
2539 rtx target;
2540 rtx result;
2541 rtx equiv;
2542 {
2543 rtx prev, next, first, last, insn;
2544
2545 /* First emit all insns that set pseudos. Remove them from the list as
2546 we go. Avoid insns that set pseudos which were referenced in previous
2547 insns. These can be generated by move_by_pieces, for example,
2548 to update an address. Similarly, avoid insns that reference things
2549 set in previous insns. */
2550
2551 for (insn = insns; insn; insn = next)
2552 {
2553 rtx set = single_set (insn);
2554
2555 next = NEXT_INSN (insn);
2556
2557 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2558 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2559 && (insn == insns
2560 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2561 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2562 && ! modified_in_p (SET_SRC (set), insns)
2563 && ! modified_between_p (SET_SRC (set), insns, insn))))
2564 {
2565 if (PREV_INSN (insn))
2566 NEXT_INSN (PREV_INSN (insn)) = next;
2567 else
2568 insns = next;
2569
2570 if (next)
2571 PREV_INSN (next) = PREV_INSN (insn);
2572
2573 add_insn (insn);
2574 }
2575 }
2576
2577 prev = get_last_insn ();
2578
2579 /* Write the remaining insns followed by the final copy. */
2580
2581 for (insn = insns; insn; insn = next)
2582 {
2583 next = NEXT_INSN (insn);
2584
2585 add_insn (insn);
2586 }
2587
2588 last = emit_move_insn (target, result);
2589 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2590 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2591
2592 if (prev == 0)
2593 first = get_insns ();
2594 else
2595 first = NEXT_INSN (prev);
2596
2597 /* Encapsulate the block so it gets manipulated as a unit. */
2598 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2599 REG_NOTES (first));
2600 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2601 }
2602 \f
2603 /* Generate code to store zero in X. */
2604
2605 void
2606 emit_clr_insn (x)
2607 rtx x;
2608 {
2609 emit_move_insn (x, const0_rtx);
2610 }
2611
2612 /* Generate code to store 1 in X
2613 assuming it contains zero beforehand. */
2614
2615 void
2616 emit_0_to_1_insn (x)
2617 rtx x;
2618 {
2619 emit_move_insn (x, const1_rtx);
2620 }
2621
2622 /* Generate code to compare X with Y
2623 so that the condition codes are set.
2624
2625 MODE is the mode of the inputs (in case they are const_int).
2626 UNSIGNEDP nonzero says that X and Y are unsigned;
2627 this matters if they need to be widened.
2628
2629 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2630 and ALIGN specifies the known shared alignment of X and Y.
2631
2632 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2633 It is ignored for fixed-point and block comparisons;
2634 it is used only for floating-point comparisons. */
2635
2636 void
2637 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2638 rtx x, y;
2639 enum rtx_code comparison;
2640 rtx size;
2641 enum machine_mode mode;
2642 int unsignedp;
2643 int align;
2644 {
2645 enum mode_class class;
2646 enum machine_mode wider_mode;
2647
2648 class = GET_MODE_CLASS (mode);
2649
2650 /* They could both be VOIDmode if both args are immediate constants,
2651 but we should fold that at an earlier stage.
2652 With no special code here, this will call abort,
2653 reminding the programmer to implement such folding. */
2654
2655 if (mode != BLKmode && flag_force_mem)
2656 {
2657 x = force_not_mem (x);
2658 y = force_not_mem (y);
2659 }
2660
2661 /* If we are inside an appropriately-short loop and one operand is an
2662 expensive constant, force it into a register. */
2663 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2664 x = force_reg (mode, x);
2665
2666 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2667 y = force_reg (mode, y);
2668
2669 /* Don't let both operands fail to indicate the mode. */
2670 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2671 x = force_reg (mode, x);
2672
2673 /* Handle all BLKmode compares. */
2674
2675 if (mode == BLKmode)
2676 {
2677 emit_queue ();
2678 x = protect_from_queue (x, 0);
2679 y = protect_from_queue (y, 0);
2680
2681 if (size == 0)
2682 abort ();
2683 #ifdef HAVE_cmpstrqi
2684 if (HAVE_cmpstrqi
2685 && GET_CODE (size) == CONST_INT
2686 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2687 {
2688 enum machine_mode result_mode
2689 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2690 rtx result = gen_reg_rtx (result_mode);
2691 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2692 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2693 result_mode, 0, 0);
2694 }
2695 else
2696 #endif
2697 #ifdef HAVE_cmpstrhi
2698 if (HAVE_cmpstrhi
2699 && GET_CODE (size) == CONST_INT
2700 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2701 {
2702 enum machine_mode result_mode
2703 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2704 rtx result = gen_reg_rtx (result_mode);
2705 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2706 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2707 result_mode, 0, 0);
2708 }
2709 else
2710 #endif
2711 #ifdef HAVE_cmpstrsi
2712 if (HAVE_cmpstrsi)
2713 {
2714 enum machine_mode result_mode
2715 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2716 rtx result = gen_reg_rtx (result_mode);
2717 size = protect_from_queue (size, 0);
2718 emit_insn (gen_cmpstrsi (result, x, y,
2719 convert_to_mode (SImode, size, 1),
2720 GEN_INT (align)));
2721 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2722 result_mode, 0, 0);
2723 }
2724 else
2725 #endif
2726 {
2727 #ifdef TARGET_MEM_FUNCTIONS
2728 emit_library_call (memcmp_libfunc, 0,
2729 TYPE_MODE (integer_type_node), 3,
2730 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2731 size, Pmode);
2732 #else
2733 emit_library_call (bcmp_libfunc, 0,
2734 TYPE_MODE (integer_type_node), 3,
2735 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2736 size, Pmode);
2737 #endif
2738 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2739 const0_rtx, comparison, NULL_RTX,
2740 TYPE_MODE (integer_type_node), 0, 0);
2741 }
2742 return;
2743 }
2744
2745 /* Handle some compares against zero. */
2746
2747 if (y == CONST0_RTX (mode)
2748 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2749 {
2750 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2751
2752 emit_queue ();
2753 x = protect_from_queue (x, 0);
2754 y = protect_from_queue (y, 0);
2755
2756 /* Now, if insn does accept these operands, put them into pseudos. */
2757 if (! (*insn_operand_predicate[icode][0])
2758 (x, insn_operand_mode[icode][0]))
2759 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2760
2761 emit_insn (GEN_FCN (icode) (x));
2762 return;
2763 }
2764
2765 /* Handle compares for which there is a directly suitable insn. */
2766
2767 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2768 {
2769 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2770
2771 emit_queue ();
2772 x = protect_from_queue (x, 0);
2773 y = protect_from_queue (y, 0);
2774
2775 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2776 if (! (*insn_operand_predicate[icode][0])
2777 (x, insn_operand_mode[icode][0]))
2778 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2779
2780 if (! (*insn_operand_predicate[icode][1])
2781 (y, insn_operand_mode[icode][1]))
2782 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2783
2784 emit_insn (GEN_FCN (icode) (x, y));
2785 return;
2786 }
2787
2788 /* Try widening if we can find a direct insn that way. */
2789
2790 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2791 {
2792 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2793 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2794 {
2795 if (cmp_optab->handlers[(int) wider_mode].insn_code
2796 != CODE_FOR_nothing)
2797 {
2798 x = protect_from_queue (x, 0);
2799 y = protect_from_queue (y, 0);
2800 x = convert_modes (wider_mode, mode, x, unsignedp);
2801 y = convert_modes (wider_mode, mode, y, unsignedp);
2802 emit_cmp_insn (x, y, comparison, NULL_RTX,
2803 wider_mode, unsignedp, align);
2804 return;
2805 }
2806 }
2807 }
2808
2809 /* Handle a lib call just for the mode we are using. */
2810
2811 if (cmp_optab->handlers[(int) mode].libfunc
2812 && class != MODE_FLOAT)
2813 {
2814 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2815 /* If we want unsigned, and this mode has a distinct unsigned
2816 comparison routine, use that. */
2817 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2818 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2819
2820 emit_library_call (libfunc, 1,
2821 word_mode, 2, x, mode, y, mode);
2822
2823 /* Integer comparison returns a result that must be compared against 1,
2824 so that even if we do an unsigned compare afterward,
2825 there is still a value that can represent the result "less than". */
2826
2827 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2828 comparison, NULL_RTX, word_mode, unsignedp, 0);
2829 return;
2830 }
2831
2832 if (class == MODE_FLOAT)
2833 emit_float_lib_cmp (x, y, comparison);
2834
2835 else
2836 abort ();
2837 }
2838
2839 /* Nonzero if a compare of mode MODE can be done straightforwardly
2840 (without splitting it into pieces). */
2841
2842 int
2843 can_compare_p (mode)
2844 enum machine_mode mode;
2845 {
2846 do
2847 {
2848 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2849 return 1;
2850 mode = GET_MODE_WIDER_MODE (mode);
2851 } while (mode != VOIDmode);
2852
2853 return 0;
2854 }
2855 \f
2856 /* Emit a library call comparison between floating point X and Y.
2857 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2858
2859 void
2860 emit_float_lib_cmp (x, y, comparison)
2861 rtx x, y;
2862 enum rtx_code comparison;
2863 {
2864 enum machine_mode mode = GET_MODE (x);
2865 rtx libfunc = 0;
2866
2867 if (mode == HFmode)
2868 switch (comparison)
2869 {
2870 case EQ:
2871 libfunc = eqhf2_libfunc;
2872 break;
2873
2874 case NE:
2875 libfunc = nehf2_libfunc;
2876 break;
2877
2878 case GT:
2879 libfunc = gthf2_libfunc;
2880 break;
2881
2882 case GE:
2883 libfunc = gehf2_libfunc;
2884 break;
2885
2886 case LT:
2887 libfunc = lthf2_libfunc;
2888 break;
2889
2890 case LE:
2891 libfunc = lehf2_libfunc;
2892 break;
2893 }
2894 else if (mode == SFmode)
2895 switch (comparison)
2896 {
2897 case EQ:
2898 libfunc = eqsf2_libfunc;
2899 break;
2900
2901 case NE:
2902 libfunc = nesf2_libfunc;
2903 break;
2904
2905 case GT:
2906 libfunc = gtsf2_libfunc;
2907 break;
2908
2909 case GE:
2910 libfunc = gesf2_libfunc;
2911 break;
2912
2913 case LT:
2914 libfunc = ltsf2_libfunc;
2915 break;
2916
2917 case LE:
2918 libfunc = lesf2_libfunc;
2919 break;
2920 }
2921 else if (mode == DFmode)
2922 switch (comparison)
2923 {
2924 case EQ:
2925 libfunc = eqdf2_libfunc;
2926 break;
2927
2928 case NE:
2929 libfunc = nedf2_libfunc;
2930 break;
2931
2932 case GT:
2933 libfunc = gtdf2_libfunc;
2934 break;
2935
2936 case GE:
2937 libfunc = gedf2_libfunc;
2938 break;
2939
2940 case LT:
2941 libfunc = ltdf2_libfunc;
2942 break;
2943
2944 case LE:
2945 libfunc = ledf2_libfunc;
2946 break;
2947 }
2948 else if (mode == XFmode)
2949 switch (comparison)
2950 {
2951 case EQ:
2952 libfunc = eqxf2_libfunc;
2953 break;
2954
2955 case NE:
2956 libfunc = nexf2_libfunc;
2957 break;
2958
2959 case GT:
2960 libfunc = gtxf2_libfunc;
2961 break;
2962
2963 case GE:
2964 libfunc = gexf2_libfunc;
2965 break;
2966
2967 case LT:
2968 libfunc = ltxf2_libfunc;
2969 break;
2970
2971 case LE:
2972 libfunc = lexf2_libfunc;
2973 break;
2974 }
2975 else if (mode == TFmode)
2976 switch (comparison)
2977 {
2978 case EQ:
2979 libfunc = eqtf2_libfunc;
2980 break;
2981
2982 case NE:
2983 libfunc = netf2_libfunc;
2984 break;
2985
2986 case GT:
2987 libfunc = gttf2_libfunc;
2988 break;
2989
2990 case GE:
2991 libfunc = getf2_libfunc;
2992 break;
2993
2994 case LT:
2995 libfunc = lttf2_libfunc;
2996 break;
2997
2998 case LE:
2999 libfunc = letf2_libfunc;
3000 break;
3001 }
3002 else
3003 {
3004 enum machine_mode wider_mode;
3005
3006 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3007 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3008 {
3009 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3010 != CODE_FOR_nothing)
3011 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3012 {
3013 x = protect_from_queue (x, 0);
3014 y = protect_from_queue (y, 0);
3015 x = convert_to_mode (wider_mode, x, 0);
3016 y = convert_to_mode (wider_mode, y, 0);
3017 emit_float_lib_cmp (x, y, comparison);
3018 return;
3019 }
3020 }
3021 abort ();
3022 }
3023
3024 if (libfunc == 0)
3025 abort ();
3026
3027 emit_library_call (libfunc, 1,
3028 word_mode, 2, x, mode, y, mode);
3029
3030 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
3031 NULL_RTX, word_mode, 0, 0);
3032 }
3033 \f
3034 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3035
3036 void
3037 emit_indirect_jump (loc)
3038 rtx loc;
3039 {
3040 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3041 (loc, Pmode)))
3042 loc = copy_to_mode_reg (Pmode, loc);
3043
3044 emit_jump_insn (gen_indirect_jump (loc));
3045 emit_barrier ();
3046 }
3047 \f
3048 /* These three functions generate an insn body and return it
3049 rather than emitting the insn.
3050
3051 They do not protect from queued increments,
3052 because they may be used 1) in protect_from_queue itself
3053 and 2) in other passes where there is no queue. */
3054
3055 /* Generate and return an insn body to add Y to X. */
3056
3057 rtx
3058 gen_add2_insn (x, y)
3059 rtx x, y;
3060 {
3061 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3062
3063 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3064 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3065 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3066 abort ();
3067
3068 return (GEN_FCN (icode) (x, x, y));
3069 }
3070
3071 int
3072 have_add2_insn (mode)
3073 enum machine_mode mode;
3074 {
3075 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3076 }
3077
3078 /* Generate and return an insn body to subtract Y from X. */
3079
3080 rtx
3081 gen_sub2_insn (x, y)
3082 rtx x, y;
3083 {
3084 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3085
3086 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3087 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3088 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3089 abort ();
3090
3091 return (GEN_FCN (icode) (x, x, y));
3092 }
3093
3094 int
3095 have_sub2_insn (mode)
3096 enum machine_mode mode;
3097 {
3098 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3099 }
3100
3101 /* Generate the body of an instruction to copy Y into X.
3102 It may be a SEQUENCE, if one insn isn't enough. */
3103
3104 rtx
3105 gen_move_insn (x, y)
3106 rtx x, y;
3107 {
3108 register enum machine_mode mode = GET_MODE (x);
3109 enum insn_code insn_code;
3110 rtx seq;
3111
3112 if (mode == VOIDmode)
3113 mode = GET_MODE (y);
3114
3115 insn_code = mov_optab->handlers[(int) mode].insn_code;
3116
3117 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3118 find a mode to do it in. If we have a movcc, use it. Otherwise,
3119 find the MODE_INT mode of the same width. */
3120
3121 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3122 {
3123 enum machine_mode tmode = VOIDmode;
3124 rtx x1 = x, y1 = y;
3125
3126 if (mode != CCmode
3127 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3128 tmode = CCmode;
3129 else
3130 for (tmode = QImode; tmode != VOIDmode;
3131 tmode = GET_MODE_WIDER_MODE (tmode))
3132 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3133 break;
3134
3135 if (tmode == VOIDmode)
3136 abort ();
3137
3138 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3139 may call change_address which is not appropriate if we were
3140 called when a reload was in progress. We don't have to worry
3141 about changing the address since the size in bytes is supposed to
3142 be the same. Copy the MEM to change the mode and move any
3143 substitutions from the old MEM to the new one. */
3144
3145 if (reload_in_progress)
3146 {
3147 x = gen_lowpart_common (tmode, x1);
3148 if (x == 0 && GET_CODE (x1) == MEM)
3149 {
3150 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3151 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3152 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3153 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3154 copy_replacements (x1, x);
3155 }
3156
3157 y = gen_lowpart_common (tmode, y1);
3158 if (y == 0 && GET_CODE (y1) == MEM)
3159 {
3160 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3161 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3162 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3163 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3164 copy_replacements (y1, y);
3165 }
3166 }
3167 else
3168 {
3169 x = gen_lowpart (tmode, x);
3170 y = gen_lowpart (tmode, y);
3171 }
3172
3173 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3174 return (GEN_FCN (insn_code) (x, y));
3175 }
3176
3177 start_sequence ();
3178 emit_move_insn_1 (x, y);
3179 seq = gen_sequence ();
3180 end_sequence ();
3181 return seq;
3182 }
3183 \f
3184 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3185 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3186 no such operation exists, CODE_FOR_nothing will be returned. */
3187
3188 enum insn_code
3189 can_extend_p (to_mode, from_mode, unsignedp)
3190 enum machine_mode to_mode, from_mode;
3191 int unsignedp;
3192 {
3193 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3194 }
3195
3196 /* Generate the body of an insn to extend Y (with mode MFROM)
3197 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3198
3199 rtx
3200 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3201 rtx x, y;
3202 enum machine_mode mto, mfrom;
3203 int unsignedp;
3204 {
3205 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3206 }
3207 \f
3208 /* can_fix_p and can_float_p say whether the target machine
3209 can directly convert a given fixed point type to
3210 a given floating point type, or vice versa.
3211 The returned value is the CODE_FOR_... value to use,
3212 or CODE_FOR_nothing if these modes cannot be directly converted.
3213
3214 *TRUNCP_PTR is set to 1 if it is necessary to output
3215 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3216
3217 static enum insn_code
3218 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3219 enum machine_mode fltmode, fixmode;
3220 int unsignedp;
3221 int *truncp_ptr;
3222 {
3223 *truncp_ptr = 0;
3224 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3225 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3226
3227 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3228 {
3229 *truncp_ptr = 1;
3230 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3231 }
3232 return CODE_FOR_nothing;
3233 }
3234
3235 static enum insn_code
3236 can_float_p (fltmode, fixmode, unsignedp)
3237 enum machine_mode fixmode, fltmode;
3238 int unsignedp;
3239 {
3240 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3241 }
3242 \f
3243 /* Generate code to convert FROM to floating point
3244 and store in TO. FROM must be fixed point and not VOIDmode.
3245 UNSIGNEDP nonzero means regard FROM as unsigned.
3246 Normally this is done by correcting the final value
3247 if it is negative. */
3248
3249 void
3250 expand_float (to, from, unsignedp)
3251 rtx to, from;
3252 int unsignedp;
3253 {
3254 enum insn_code icode;
3255 register rtx target = to;
3256 enum machine_mode fmode, imode;
3257
3258 /* Crash now, because we won't be able to decide which mode to use. */
3259 if (GET_MODE (from) == VOIDmode)
3260 abort ();
3261
3262 /* Look for an insn to do the conversion. Do it in the specified
3263 modes if possible; otherwise convert either input, output or both to
3264 wider mode. If the integer mode is wider than the mode of FROM,
3265 we can do the conversion signed even if the input is unsigned. */
3266
3267 for (imode = GET_MODE (from); imode != VOIDmode;
3268 imode = GET_MODE_WIDER_MODE (imode))
3269 for (fmode = GET_MODE (to); fmode != VOIDmode;
3270 fmode = GET_MODE_WIDER_MODE (fmode))
3271 {
3272 int doing_unsigned = unsignedp;
3273
3274 icode = can_float_p (fmode, imode, unsignedp);
3275 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3276 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3277
3278 if (icode != CODE_FOR_nothing)
3279 {
3280 to = protect_from_queue (to, 1);
3281 from = protect_from_queue (from, 0);
3282
3283 if (imode != GET_MODE (from))
3284 from = convert_to_mode (imode, from, unsignedp);
3285
3286 if (fmode != GET_MODE (to))
3287 target = gen_reg_rtx (fmode);
3288
3289 emit_unop_insn (icode, target, from,
3290 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3291
3292 if (target != to)
3293 convert_move (to, target, 0);
3294 return;
3295 }
3296 }
3297
3298 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3299
3300 /* Unsigned integer, and no way to convert directly.
3301 Convert as signed, then conditionally adjust the result. */
3302 if (unsignedp)
3303 {
3304 rtx label = gen_label_rtx ();
3305 rtx temp;
3306 REAL_VALUE_TYPE offset;
3307
3308 emit_queue ();
3309
3310 to = protect_from_queue (to, 1);
3311 from = protect_from_queue (from, 0);
3312
3313 if (flag_force_mem)
3314 from = force_not_mem (from);
3315
3316 /* Look for a usable floating mode FMODE wider than the source and at
3317 least as wide as the target. Using FMODE will avoid rounding woes
3318 with unsigned values greater than the signed maximum value. */
3319
3320 for (fmode = GET_MODE (to); fmode != VOIDmode;
3321 fmode = GET_MODE_WIDER_MODE (fmode))
3322 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3323 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3324 break;
3325
3326 if (fmode == VOIDmode)
3327 {
3328 /* There is no such mode. Pretend the target is wide enough. */
3329 fmode = GET_MODE (to);
3330
3331 /* Avoid double-rounding when TO is narrower than FROM. */
3332 if ((significand_size (fmode) + 1)
3333 < GET_MODE_BITSIZE (GET_MODE (from)))
3334 {
3335 rtx temp1;
3336 rtx neglabel = gen_label_rtx ();
3337
3338 /* Don't use TARGET if it isn't a register, is a hard register,
3339 or is the wrong mode. */
3340 if (GET_CODE (target) != REG
3341 || REGNO (target) < FIRST_PSEUDO_REGISTER
3342 || GET_MODE (target) != fmode)
3343 target = gen_reg_rtx (fmode);
3344
3345 imode = GET_MODE (from);
3346 do_pending_stack_adjust ();
3347
3348 /* Test whether the sign bit is set. */
3349 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3350 emit_jump_insn (gen_blt (neglabel));
3351
3352 /* The sign bit is not set. Convert as signed. */
3353 expand_float (target, from, 0);
3354 emit_jump_insn (gen_jump (label));
3355
3356 /* The sign bit is set.
3357 Convert to a usable (positive signed) value by shifting right
3358 one bit, while remembering if a nonzero bit was shifted
3359 out; i.e., compute (from & 1) | (from >> 1). */
3360
3361 emit_label (neglabel);
3362 temp = expand_binop (imode, and_optab, from, const1_rtx,
3363 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3364 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3365 NULL_RTX, 1);
3366 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3367 OPTAB_LIB_WIDEN);
3368 expand_float (target, temp, 0);
3369
3370 /* Multiply by 2 to undo the shift above. */
3371 temp = expand_binop (fmode, add_optab, target, target,
3372 target, 0, OPTAB_LIB_WIDEN);
3373 if (temp != target)
3374 emit_move_insn (target, temp);
3375
3376 do_pending_stack_adjust ();
3377 emit_label (label);
3378 goto done;
3379 }
3380 }
3381
3382 /* If we are about to do some arithmetic to correct for an
3383 unsigned operand, do it in a pseudo-register. */
3384
3385 if (GET_MODE (to) != fmode
3386 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3387 target = gen_reg_rtx (fmode);
3388
3389 /* Convert as signed integer to floating. */
3390 expand_float (target, from, 0);
3391
3392 /* If FROM is negative (and therefore TO is negative),
3393 correct its value by 2**bitwidth. */
3394
3395 do_pending_stack_adjust ();
3396 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3397 emit_jump_insn (gen_bge (label));
3398
3399 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3400 Rather than setting up a dconst_dot_5, let's hope SCO
3401 fixes the bug. */
3402 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3403 temp = expand_binop (fmode, add_optab, target,
3404 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3405 target, 0, OPTAB_LIB_WIDEN);
3406 if (temp != target)
3407 emit_move_insn (target, temp);
3408
3409 do_pending_stack_adjust ();
3410 emit_label (label);
3411 goto done;
3412 }
3413 #endif
3414
3415 /* No hardware instruction available; call a library routine to convert from
3416 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3417 {
3418 rtx libfcn;
3419 rtx insns;
3420 rtx value;
3421
3422 to = protect_from_queue (to, 1);
3423 from = protect_from_queue (from, 0);
3424
3425 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3426 from = convert_to_mode (SImode, from, unsignedp);
3427
3428 if (flag_force_mem)
3429 from = force_not_mem (from);
3430
3431 if (GET_MODE (to) == SFmode)
3432 {
3433 if (GET_MODE (from) == SImode)
3434 libfcn = floatsisf_libfunc;
3435 else if (GET_MODE (from) == DImode)
3436 libfcn = floatdisf_libfunc;
3437 else if (GET_MODE (from) == TImode)
3438 libfcn = floattisf_libfunc;
3439 else
3440 abort ();
3441 }
3442 else if (GET_MODE (to) == DFmode)
3443 {
3444 if (GET_MODE (from) == SImode)
3445 libfcn = floatsidf_libfunc;
3446 else if (GET_MODE (from) == DImode)
3447 libfcn = floatdidf_libfunc;
3448 else if (GET_MODE (from) == TImode)
3449 libfcn = floattidf_libfunc;
3450 else
3451 abort ();
3452 }
3453 else if (GET_MODE (to) == XFmode)
3454 {
3455 if (GET_MODE (from) == SImode)
3456 libfcn = floatsixf_libfunc;
3457 else if (GET_MODE (from) == DImode)
3458 libfcn = floatdixf_libfunc;
3459 else if (GET_MODE (from) == TImode)
3460 libfcn = floattixf_libfunc;
3461 else
3462 abort ();
3463 }
3464 else if (GET_MODE (to) == TFmode)
3465 {
3466 if (GET_MODE (from) == SImode)
3467 libfcn = floatsitf_libfunc;
3468 else if (GET_MODE (from) == DImode)
3469 libfcn = floatditf_libfunc;
3470 else if (GET_MODE (from) == TImode)
3471 libfcn = floattitf_libfunc;
3472 else
3473 abort ();
3474 }
3475 else
3476 abort ();
3477
3478 start_sequence ();
3479
3480 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3481 GET_MODE (to),
3482 1, from, GET_MODE (from));
3483 insns = get_insns ();
3484 end_sequence ();
3485
3486 emit_libcall_block (insns, target, value,
3487 gen_rtx (FLOAT, GET_MODE (to), from));
3488 }
3489
3490 done:
3491
3492 /* Copy result to requested destination
3493 if we have been computing in a temp location. */
3494
3495 if (target != to)
3496 {
3497 if (GET_MODE (target) == GET_MODE (to))
3498 emit_move_insn (to, target);
3499 else
3500 convert_move (to, target, 0);
3501 }
3502 }
3503 \f
3504 /* expand_fix: generate code to convert FROM to fixed point
3505 and store in TO. FROM must be floating point. */
3506
3507 static rtx
3508 ftruncify (x)
3509 rtx x;
3510 {
3511 rtx temp = gen_reg_rtx (GET_MODE (x));
3512 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3513 }
3514
3515 void
3516 expand_fix (to, from, unsignedp)
3517 register rtx to, from;
3518 int unsignedp;
3519 {
3520 enum insn_code icode;
3521 register rtx target = to;
3522 enum machine_mode fmode, imode;
3523 int must_trunc = 0;
3524 rtx libfcn = 0;
3525
3526 /* We first try to find a pair of modes, one real and one integer, at
3527 least as wide as FROM and TO, respectively, in which we can open-code
3528 this conversion. If the integer mode is wider than the mode of TO,
3529 we can do the conversion either signed or unsigned. */
3530
3531 for (imode = GET_MODE (to); imode != VOIDmode;
3532 imode = GET_MODE_WIDER_MODE (imode))
3533 for (fmode = GET_MODE (from); fmode != VOIDmode;
3534 fmode = GET_MODE_WIDER_MODE (fmode))
3535 {
3536 int doing_unsigned = unsignedp;
3537
3538 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3539 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3540 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3541
3542 if (icode != CODE_FOR_nothing)
3543 {
3544 to = protect_from_queue (to, 1);
3545 from = protect_from_queue (from, 0);
3546
3547 if (fmode != GET_MODE (from))
3548 from = convert_to_mode (fmode, from, 0);
3549
3550 if (must_trunc)
3551 from = ftruncify (from);
3552
3553 if (imode != GET_MODE (to))
3554 target = gen_reg_rtx (imode);
3555
3556 emit_unop_insn (icode, target, from,
3557 doing_unsigned ? UNSIGNED_FIX : FIX);
3558 if (target != to)
3559 convert_move (to, target, unsignedp);
3560 return;
3561 }
3562 }
3563
3564 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3565 /* For an unsigned conversion, there is one more way to do it.
3566 If we have a signed conversion, we generate code that compares
3567 the real value to the largest representable positive number. If if
3568 is smaller, the conversion is done normally. Otherwise, subtract
3569 one plus the highest signed number, convert, and add it back.
3570
3571 We only need to check all real modes, since we know we didn't find
3572 anything with a wider integer mode. */
3573
3574 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3575 for (fmode = GET_MODE (from); fmode != VOIDmode;
3576 fmode = GET_MODE_WIDER_MODE (fmode))
3577 /* Make sure we won't lose significant bits doing this. */
3578 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3579 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3580 &must_trunc))
3581 {
3582 int bitsize;
3583 REAL_VALUE_TYPE offset;
3584 rtx limit, lab1, lab2, insn;
3585
3586 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3587 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3588 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3589 lab1 = gen_label_rtx ();
3590 lab2 = gen_label_rtx ();
3591
3592 emit_queue ();
3593 to = protect_from_queue (to, 1);
3594 from = protect_from_queue (from, 0);
3595
3596 if (flag_force_mem)
3597 from = force_not_mem (from);
3598
3599 if (fmode != GET_MODE (from))
3600 from = convert_to_mode (fmode, from, 0);
3601
3602 /* See if we need to do the subtraction. */
3603 do_pending_stack_adjust ();
3604 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3605 emit_jump_insn (gen_bge (lab1));
3606
3607 /* If not, do the signed "fix" and branch around fixup code. */
3608 expand_fix (to, from, 0);
3609 emit_jump_insn (gen_jump (lab2));
3610 emit_barrier ();
3611
3612 /* Otherwise, subtract 2**(N-1), convert to signed number,
3613 then add 2**(N-1). Do the addition using XOR since this
3614 will often generate better code. */
3615 emit_label (lab1);
3616 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3617 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3618 expand_fix (to, target, 0);
3619 target = expand_binop (GET_MODE (to), xor_optab, to,
3620 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3621 to, 1, OPTAB_LIB_WIDEN);
3622
3623 if (target != to)
3624 emit_move_insn (to, target);
3625
3626 emit_label (lab2);
3627
3628 /* Make a place for a REG_NOTE and add it. */
3629 insn = emit_move_insn (to, to);
3630 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3631 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3632 copy_rtx (from)),
3633 REG_NOTES (insn));
3634
3635 return;
3636 }
3637 #endif
3638
3639 /* We can't do it with an insn, so use a library call. But first ensure
3640 that the mode of TO is at least as wide as SImode, since those are the
3641 only library calls we know about. */
3642
3643 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3644 {
3645 target = gen_reg_rtx (SImode);
3646
3647 expand_fix (target, from, unsignedp);
3648 }
3649 else if (GET_MODE (from) == SFmode)
3650 {
3651 if (GET_MODE (to) == SImode)
3652 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3653 else if (GET_MODE (to) == DImode)
3654 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3655 else if (GET_MODE (to) == TImode)
3656 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3657 else
3658 abort ();
3659 }
3660 else if (GET_MODE (from) == DFmode)
3661 {
3662 if (GET_MODE (to) == SImode)
3663 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3664 else if (GET_MODE (to) == DImode)
3665 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3666 else if (GET_MODE (to) == TImode)
3667 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3668 else
3669 abort ();
3670 }
3671 else if (GET_MODE (from) == XFmode)
3672 {
3673 if (GET_MODE (to) == SImode)
3674 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3675 else if (GET_MODE (to) == DImode)
3676 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3677 else if (GET_MODE (to) == TImode)
3678 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3679 else
3680 abort ();
3681 }
3682 else if (GET_MODE (from) == TFmode)
3683 {
3684 if (GET_MODE (to) == SImode)
3685 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3686 else if (GET_MODE (to) == DImode)
3687 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3688 else if (GET_MODE (to) == TImode)
3689 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3690 else
3691 abort ();
3692 }
3693 else
3694 abort ();
3695
3696 if (libfcn)
3697 {
3698 rtx insns;
3699 rtx value;
3700
3701 to = protect_from_queue (to, 1);
3702 from = protect_from_queue (from, 0);
3703
3704 if (flag_force_mem)
3705 from = force_not_mem (from);
3706
3707 start_sequence ();
3708
3709 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3710
3711 1, from, GET_MODE (from));
3712 insns = get_insns ();
3713 end_sequence ();
3714
3715 emit_libcall_block (insns, target, value,
3716 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3717 GET_MODE (to), from));
3718 }
3719
3720 if (GET_MODE (to) == GET_MODE (target))
3721 emit_move_insn (to, target);
3722 else
3723 convert_move (to, target, 0);
3724 }
3725 \f
3726 static optab
3727 init_optab (code)
3728 enum rtx_code code;
3729 {
3730 int i;
3731 optab op = (optab) xmalloc (sizeof (struct optab));
3732 op->code = code;
3733 for (i = 0; i < NUM_MACHINE_MODES; i++)
3734 {
3735 op->handlers[i].insn_code = CODE_FOR_nothing;
3736 op->handlers[i].libfunc = 0;
3737 }
3738
3739 if (code != UNKNOWN)
3740 code_to_optab[(int) code] = op;
3741
3742 return op;
3743 }
3744
3745 /* Initialize the libfunc fields of an entire group of entries in some
3746 optab. Each entry is set equal to a string consisting of a leading
3747 pair of underscores followed by a generic operation name followed by
3748 a mode name (downshifted to lower case) followed by a single character
3749 representing the number of operands for the given operation (which is
3750 usually one of the characters '2', '3', or '4').
3751
3752 OPTABLE is the table in which libfunc fields are to be initialized.
3753 FIRST_MODE is the first machine mode index in the given optab to
3754 initialize.
3755 LAST_MODE is the last machine mode index in the given optab to
3756 initialize.
3757 OPNAME is the generic (string) name of the operation.
3758 SUFFIX is the character which specifies the number of operands for
3759 the given generic operation.
3760 */
3761
3762 static void
3763 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3764 register optab optable;
3765 register int first_mode;
3766 register int last_mode;
3767 register char *opname;
3768 register char suffix;
3769 {
3770 register int mode;
3771 register unsigned opname_len = strlen (opname);
3772
3773 for (mode = first_mode; (int) mode <= (int) last_mode;
3774 mode = (enum machine_mode) ((int) mode + 1))
3775 {
3776 register char *mname = mode_name[(int) mode];
3777 register unsigned mname_len = strlen (mname);
3778 register char *libfunc_name
3779 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3780 register char *p;
3781 register char *q;
3782
3783 p = libfunc_name;
3784 *p++ = '_';
3785 *p++ = '_';
3786 for (q = opname; *q; )
3787 *p++ = *q++;
3788 for (q = mname; *q; q++)
3789 *p++ = tolower (*q);
3790 *p++ = suffix;
3791 *p++ = '\0';
3792 optable->handlers[(int) mode].libfunc
3793 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3794 }
3795 }
3796
3797 /* Initialize the libfunc fields of an entire group of entries in some
3798 optab which correspond to all integer mode operations. The parameters
3799 have the same meaning as similarly named ones for the `init_libfuncs'
3800 routine. (See above). */
3801
3802 static void
3803 init_integral_libfuncs (optable, opname, suffix)
3804 register optab optable;
3805 register char *opname;
3806 register char suffix;
3807 {
3808 init_libfuncs (optable, SImode, TImode, opname, suffix);
3809 }
3810
3811 /* Initialize the libfunc fields of an entire group of entries in some
3812 optab which correspond to all real mode operations. The parameters
3813 have the same meaning as similarly named ones for the `init_libfuncs'
3814 routine. (See above). */
3815
3816 static void
3817 init_floating_libfuncs (optable, opname, suffix)
3818 register optab optable;
3819 register char *opname;
3820 register char suffix;
3821 {
3822 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3823 }
3824
3825 /* Initialize the libfunc fields of an entire group of entries in some
3826 optab which correspond to all complex floating modes. The parameters
3827 have the same meaning as similarly named ones for the `init_libfuncs'
3828 routine. (See above). */
3829
3830 static void
3831 init_complex_libfuncs (optable, opname, suffix)
3832 register optab optable;
3833 register char *opname;
3834 register char suffix;
3835 {
3836 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3837 }
3838
3839 /* Call this once to initialize the contents of the optabs
3840 appropriately for the current target machine. */
3841
3842 void
3843 init_optabs ()
3844 {
3845 int i, j;
3846 enum insn_code *p;
3847
3848 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3849
3850 for (p = fixtab[0][0];
3851 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3852 p++)
3853 *p = CODE_FOR_nothing;
3854
3855 for (p = fixtrunctab[0][0];
3856 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3857 p++)
3858 *p = CODE_FOR_nothing;
3859
3860 for (p = floattab[0][0];
3861 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3862 p++)
3863 *p = CODE_FOR_nothing;
3864
3865 for (p = extendtab[0][0];
3866 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3867 p++)
3868 *p = CODE_FOR_nothing;
3869
3870 for (i = 0; i < NUM_RTX_CODE; i++)
3871 setcc_gen_code[i] = CODE_FOR_nothing;
3872
3873 add_optab = init_optab (PLUS);
3874 sub_optab = init_optab (MINUS);
3875 smul_optab = init_optab (MULT);
3876 smul_highpart_optab = init_optab (UNKNOWN);
3877 umul_highpart_optab = init_optab (UNKNOWN);
3878 smul_widen_optab = init_optab (UNKNOWN);
3879 umul_widen_optab = init_optab (UNKNOWN);
3880 sdiv_optab = init_optab (DIV);
3881 sdivmod_optab = init_optab (UNKNOWN);
3882 udiv_optab = init_optab (UDIV);
3883 udivmod_optab = init_optab (UNKNOWN);
3884 smod_optab = init_optab (MOD);
3885 umod_optab = init_optab (UMOD);
3886 flodiv_optab = init_optab (DIV);
3887 ftrunc_optab = init_optab (UNKNOWN);
3888 and_optab = init_optab (AND);
3889 ior_optab = init_optab (IOR);
3890 xor_optab = init_optab (XOR);
3891 ashl_optab = init_optab (ASHIFT);
3892 ashr_optab = init_optab (ASHIFTRT);
3893 lshr_optab = init_optab (LSHIFTRT);
3894 rotl_optab = init_optab (ROTATE);
3895 rotr_optab = init_optab (ROTATERT);
3896 smin_optab = init_optab (SMIN);
3897 smax_optab = init_optab (SMAX);
3898 umin_optab = init_optab (UMIN);
3899 umax_optab = init_optab (UMAX);
3900 mov_optab = init_optab (UNKNOWN);
3901 movstrict_optab = init_optab (UNKNOWN);
3902 cmp_optab = init_optab (UNKNOWN);
3903 ucmp_optab = init_optab (UNKNOWN);
3904 tst_optab = init_optab (UNKNOWN);
3905 neg_optab = init_optab (NEG);
3906 abs_optab = init_optab (ABS);
3907 one_cmpl_optab = init_optab (NOT);
3908 ffs_optab = init_optab (FFS);
3909 sqrt_optab = init_optab (SQRT);
3910 sin_optab = init_optab (UNKNOWN);
3911 cos_optab = init_optab (UNKNOWN);
3912 strlen_optab = init_optab (UNKNOWN);
3913
3914 for (i = 0; i < NUM_MACHINE_MODES; i++)
3915 {
3916 movstr_optab[i] = CODE_FOR_nothing;
3917
3918 #ifdef HAVE_SECONDARY_RELOADS
3919 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3920 #endif
3921 }
3922
3923 /* Fill in the optabs with the insns we support. */
3924 init_all_optabs ();
3925
3926 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3927 /* This flag says the same insns that convert to a signed fixnum
3928 also convert validly to an unsigned one. */
3929 for (i = 0; i < NUM_MACHINE_MODES; i++)
3930 for (j = 0; j < NUM_MACHINE_MODES; j++)
3931 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3932 #endif
3933
3934 #ifdef EXTRA_CC_MODES
3935 init_mov_optab ();
3936 #endif
3937
3938 /* Initialize the optabs with the names of the library functions. */
3939 init_integral_libfuncs (add_optab, "add", '3');
3940 init_floating_libfuncs (add_optab, "add", '3');
3941 init_integral_libfuncs (sub_optab, "sub", '3');
3942 init_floating_libfuncs (sub_optab, "sub", '3');
3943 init_integral_libfuncs (smul_optab, "mul", '3');
3944 init_floating_libfuncs (smul_optab, "mul", '3');
3945 init_integral_libfuncs (sdiv_optab, "div", '3');
3946 init_integral_libfuncs (udiv_optab, "udiv", '3');
3947 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3948 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3949 init_integral_libfuncs (smod_optab, "mod", '3');
3950 init_integral_libfuncs (umod_optab, "umod", '3');
3951 init_floating_libfuncs (flodiv_optab, "div", '3');
3952 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3953 init_integral_libfuncs (and_optab, "and", '3');
3954 init_integral_libfuncs (ior_optab, "ior", '3');
3955 init_integral_libfuncs (xor_optab, "xor", '3');
3956 init_integral_libfuncs (ashl_optab, "ashl", '3');
3957 init_integral_libfuncs (ashr_optab, "ashr", '3');
3958 init_integral_libfuncs (lshr_optab, "lshr", '3');
3959 init_integral_libfuncs (rotl_optab, "rotl", '3');
3960 init_integral_libfuncs (rotr_optab, "rotr", '3');
3961 init_integral_libfuncs (smin_optab, "min", '3');
3962 init_floating_libfuncs (smin_optab, "min", '3');
3963 init_integral_libfuncs (smax_optab, "max", '3');
3964 init_floating_libfuncs (smax_optab, "max", '3');
3965 init_integral_libfuncs (umin_optab, "umin", '3');
3966 init_integral_libfuncs (umax_optab, "umax", '3');
3967 init_integral_libfuncs (neg_optab, "neg", '2');
3968 init_floating_libfuncs (neg_optab, "neg", '2');
3969 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3970 init_integral_libfuncs (ffs_optab, "ffs", '2');
3971
3972 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3973 init_integral_libfuncs (cmp_optab, "cmp", '2');
3974 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3975 init_floating_libfuncs (cmp_optab, "cmp", '2');
3976
3977 #ifdef MULSI3_LIBCALL
3978 smul_optab->handlers[(int) SImode].libfunc
3979 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3980 #endif
3981 #ifdef MULDI3_LIBCALL
3982 smul_optab->handlers[(int) DImode].libfunc
3983 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3984 #endif
3985 #ifdef MULTI3_LIBCALL
3986 smul_optab->handlers[(int) TImode].libfunc
3987 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3988 #endif
3989
3990 #ifdef DIVSI3_LIBCALL
3991 sdiv_optab->handlers[(int) SImode].libfunc
3992 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3993 #endif
3994 #ifdef DIVDI3_LIBCALL
3995 sdiv_optab->handlers[(int) DImode].libfunc
3996 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3997 #endif
3998 #ifdef DIVTI3_LIBCALL
3999 sdiv_optab->handlers[(int) TImode].libfunc
4000 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
4001 #endif
4002
4003 #ifdef UDIVSI3_LIBCALL
4004 udiv_optab->handlers[(int) SImode].libfunc
4005 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4006 #endif
4007 #ifdef UDIVDI3_LIBCALL
4008 udiv_optab->handlers[(int) DImode].libfunc
4009 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4010 #endif
4011 #ifdef UDIVTI3_LIBCALL
4012 udiv_optab->handlers[(int) TImode].libfunc
4013 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
4014 #endif
4015
4016
4017 #ifdef MODSI3_LIBCALL
4018 smod_optab->handlers[(int) SImode].libfunc
4019 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4020 #endif
4021 #ifdef MODDI3_LIBCALL
4022 smod_optab->handlers[(int) DImode].libfunc
4023 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4024 #endif
4025 #ifdef MODTI3_LIBCALL
4026 smod_optab->handlers[(int) TImode].libfunc
4027 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
4028 #endif
4029
4030
4031 #ifdef UMODSI3_LIBCALL
4032 umod_optab->handlers[(int) SImode].libfunc
4033 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4034 #endif
4035 #ifdef UMODDI3_LIBCALL
4036 umod_optab->handlers[(int) DImode].libfunc
4037 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4038 #endif
4039 #ifdef UMODTI3_LIBCALL
4040 umod_optab->handlers[(int) TImode].libfunc
4041 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4042 #endif
4043
4044 /* Define library calls for quad FP instructions */
4045 #ifdef ADDTF3_LIBCALL
4046 add_optab->handlers[(int) TFmode].libfunc
4047 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
4048 #endif
4049 #ifdef SUBTF3_LIBCALL
4050 sub_optab->handlers[(int) TFmode].libfunc
4051 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
4052 #endif
4053 #ifdef MULTF3_LIBCALL
4054 smul_optab->handlers[(int) TFmode].libfunc
4055 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
4056 #endif
4057 #ifdef DIVTF3_LIBCALL
4058 flodiv_optab->handlers[(int) TFmode].libfunc
4059 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
4060 #endif
4061 #ifdef SQRTTF2_LIBCALL
4062 sqrt_optab->handlers[(int) TFmode].libfunc
4063 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
4064 #endif
4065
4066 /* Use cabs for DC complex abs, since systems generally have cabs.
4067 Don't define any libcall for SCmode, so that cabs will be used. */
4068 abs_optab->handlers[(int) DCmode].libfunc
4069 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4070
4071 /* The ffs function operates on `int'. */
4072 #ifndef INT_TYPE_SIZE
4073 #define INT_TYPE_SIZE BITS_PER_WORD
4074 #endif
4075 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4076 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4077
4078 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4079 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4080 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4081 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4082 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4083
4084 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4085 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4086 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4087 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4088 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4089
4090 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4091 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4092 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4093 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4094 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4095 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4096
4097 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4098 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4099 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4100 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4101 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4102 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4103
4104 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4105 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4106 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4107 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4108 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4109 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4110
4111 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4112 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4113 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4114 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4115 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4116 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4117
4118 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4119 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4120 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4121 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4122 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4123 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4124
4125 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4126 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4127 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4128 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4129 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4130 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4131
4132 /* Define library calls for quad FP instructions */
4133 #ifdef EQTF2_LIBCALL
4134 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
4135 #endif
4136 #ifdef NETF2_LIBCALL
4137 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
4138 #endif
4139 #ifdef GTTF2_LIBCALL
4140 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
4141 #endif
4142 #ifdef GETF2_LIBCALL
4143 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
4144 #endif
4145 #ifdef LTTF2_LIBCALL
4146 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
4147 #endif
4148 #ifdef LETF2_LIBCALL
4149 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
4150 #endif
4151
4152 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4153 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4154 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4155
4156 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4157 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4158 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4159
4160 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4161 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4162 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4163
4164 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4165 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4166 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4167
4168 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4169 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4170 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4171
4172 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4173 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4174 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4175
4176 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4177 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4178 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4179
4180 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4181 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4182 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4183
4184 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4185 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4186 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4187
4188 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4189 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4190 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4191
4192 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4193 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4194 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4195
4196 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4197 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4198 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4199
4200 /* Define library calls for quad FP instructions */
4201 #ifdef TRUNCTFSF2_LIBCALL
4202 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
4203 #endif
4204 #ifdef TRUNCTFDF2_LIBCALL
4205 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
4206 #endif
4207 #ifdef EXTENDSFTF2_LIBCALL
4208 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
4209 #endif
4210 #ifdef EXTENDDFTF2_LIBCALL
4211 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
4212 #endif
4213 #ifdef FLOATSITF2_LIBCALL
4214 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
4215 #endif
4216 #ifdef FIX_TRUNCTFSI2_LIBCALL
4217 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
4218 #endif
4219 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
4220 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);
4221 #endif
4222
4223 #ifdef INIT_TARGET_OPTABS
4224 /* Allow the target to add more libcalls or rename some, etc. */
4225 INIT_TARGET_OPTABS;
4226 #endif
4227 }
4228 \f
4229 #ifdef BROKEN_LDEXP
4230
4231 /* SCO 3.2 apparently has a broken ldexp. */
4232
4233 double
4234 ldexp(x,n)
4235 double x;
4236 int n;
4237 {
4238 if (n > 0)
4239 while (n--)
4240 x *= 2;
4241
4242 return x;
4243 }
4244 #endif /* BROKEN_LDEXP */
This page took 0.225332 seconds and 6 git commands to generate.