OSDN Git Service

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