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