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