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