OSDN Git Service

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