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