OSDN Git Service

* intl.h (open_quote, close_quote): New.
[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          opportunities, 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 UNOPPTAB
2151    on operand OP0, with two results to TARG0 and TARG1.
2152    We assume that the order of the operands for the instruction
2153    is TARG0, TARG1, OP0.
2154
2155    Either TARG0 or TARG1 may be zero, but what that means is that
2156    the result is not actually wanted.  We will generate it into
2157    a dummy pseudo-reg and discard it.  They may not both be zero.
2158
2159    Returns 1 if this operation can be performed; 0 if not.  */
2160
2161 int
2162 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2163                     int unsignedp)
2164 {
2165   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2166   enum mode_class class;
2167   enum machine_mode wider_mode;
2168   rtx entry_last = get_last_insn ();
2169   rtx last;
2170
2171   class = GET_MODE_CLASS (mode);
2172
2173   op0 = protect_from_queue (op0, 0);
2174
2175   if (flag_force_mem)
2176     {
2177       op0 = force_not_mem (op0);
2178     }
2179
2180   if (targ0)
2181     targ0 = protect_from_queue (targ0, 1);
2182   else
2183     targ0 = gen_reg_rtx (mode);
2184   if (targ1)
2185     targ1 = protect_from_queue (targ1, 1);
2186   else
2187     targ1 = gen_reg_rtx (mode);
2188
2189   /* Record where to go back to if we fail.  */
2190   last = get_last_insn ();
2191
2192   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2193     {
2194       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2195       enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2196       rtx pat;
2197       rtx xop0 = op0;
2198
2199       if (GET_MODE (xop0) != VOIDmode
2200           && GET_MODE (xop0) != mode0)
2201         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2202
2203       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2204       if (! (*insn_data[icode].operand[2].predicate) (xop0, mode0))
2205         xop0 = copy_to_mode_reg (mode0, xop0);
2206
2207       /* We could handle this, but we should always be called with a pseudo
2208          for our targets and all insns should take them as outputs.  */
2209       if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2210           || ! (*insn_data[icode].operand[1].predicate) (targ1, mode))
2211         abort ();
2212
2213       pat = GEN_FCN (icode) (targ0, targ1, xop0);
2214       if (pat)
2215         {
2216           emit_insn (pat);
2217           return 1;
2218         }
2219       else
2220         delete_insns_since (last);
2221     }
2222
2223   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2224
2225   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2226     {
2227       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2228            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2229         {
2230           if (unoptab->handlers[(int) wider_mode].insn_code
2231               != CODE_FOR_nothing)
2232             {
2233               rtx t0 = gen_reg_rtx (wider_mode);
2234               rtx t1 = gen_reg_rtx (wider_mode);
2235               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2236
2237               if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2238                 {
2239                   convert_move (targ0, t0, unsignedp);
2240                   convert_move (targ1, t1, unsignedp);
2241                   return 1;
2242                 }
2243               else
2244                 delete_insns_since (last);
2245             }
2246         }
2247     }
2248
2249   delete_insns_since (entry_last);
2250   return 0;
2251 }
2252 \f
2253 /* Generate code to perform an operation specified by BINOPTAB
2254    on operands OP0 and OP1, with two results to TARG1 and TARG2.
2255    We assume that the order of the operands for the instruction
2256    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2257    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2258
2259    Either TARG0 or TARG1 may be zero, but what that means is that
2260    the result is not actually wanted.  We will generate it into
2261    a dummy pseudo-reg and discard it.  They may not both be zero.
2262
2263    Returns 1 if this operation can be performed; 0 if not.  */
2264
2265 int
2266 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2267                      int unsignedp)
2268 {
2269   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2270   enum mode_class class;
2271   enum machine_mode wider_mode;
2272   rtx entry_last = get_last_insn ();
2273   rtx last;
2274
2275   class = GET_MODE_CLASS (mode);
2276
2277   op0 = protect_from_queue (op0, 0);
2278   op1 = protect_from_queue (op1, 0);
2279
2280   if (flag_force_mem)
2281     {
2282       op0 = force_not_mem (op0);
2283       op1 = force_not_mem (op1);
2284     }
2285
2286   /* If we are inside an appropriately-short loop and one operand is an
2287      expensive constant, force it into a register.  */
2288   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2289       && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2290     op0 = force_reg (mode, op0);
2291
2292   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2293       && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2294     op1 = force_reg (mode, op1);
2295
2296   if (targ0)
2297     targ0 = protect_from_queue (targ0, 1);
2298   else
2299     targ0 = gen_reg_rtx (mode);
2300   if (targ1)
2301     targ1 = protect_from_queue (targ1, 1);
2302   else
2303     targ1 = gen_reg_rtx (mode);
2304
2305   /* Record where to go back to if we fail.  */
2306   last = get_last_insn ();
2307
2308   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2309     {
2310       int icode = (int) binoptab->handlers[(int) mode].insn_code;
2311       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2312       enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2313       rtx pat;
2314       rtx xop0 = op0, xop1 = op1;
2315
2316       /* In case the insn wants input operands in modes different from
2317          those of the actual operands, convert the operands.  It would
2318          seem that we don't need to convert CONST_INTs, but we do, so
2319          that they're properly zero-extended, sign-extended or truncated
2320          for their mode.  */
2321
2322       if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2323         xop0 = convert_modes (mode0,
2324                               GET_MODE (op0) != VOIDmode
2325                               ? GET_MODE (op0)
2326                               : mode,
2327                               xop0, unsignedp);
2328
2329       if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2330         xop1 = convert_modes (mode1,
2331                               GET_MODE (op1) != VOIDmode
2332                               ? GET_MODE (op1)
2333                               : mode,
2334                               xop1, unsignedp);
2335
2336       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2337       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2338         xop0 = copy_to_mode_reg (mode0, xop0);
2339
2340       if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
2341         xop1 = copy_to_mode_reg (mode1, xop1);
2342
2343       /* We could handle this, but we should always be called with a pseudo
2344          for our targets and all insns should take them as outputs.  */
2345       if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
2346           || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
2347         abort ();
2348
2349       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2350       if (pat)
2351         {
2352           emit_insn (pat);
2353           return 1;
2354         }
2355       else
2356         delete_insns_since (last);
2357     }
2358
2359   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2360
2361   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2362     {
2363       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2364            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2365         {
2366           if (binoptab->handlers[(int) wider_mode].insn_code
2367               != CODE_FOR_nothing)
2368             {
2369               rtx t0 = gen_reg_rtx (wider_mode);
2370               rtx t1 = gen_reg_rtx (wider_mode);
2371               rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2372               rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2373
2374               if (expand_twoval_binop (binoptab, cop0, cop1,
2375                                        t0, t1, unsignedp))
2376                 {
2377                   convert_move (targ0, t0, unsignedp);
2378                   convert_move (targ1, t1, unsignedp);
2379                   return 1;
2380                 }
2381               else
2382                 delete_insns_since (last);
2383             }
2384         }
2385     }
2386
2387   delete_insns_since (entry_last);
2388   return 0;
2389 }
2390 \f
2391 /* Wrapper around expand_unop which takes an rtx code to specify
2392    the operation to perform, not an optab pointer.  All other
2393    arguments are the same.  */
2394 rtx
2395 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2396                     rtx target, int unsignedp)
2397 {
2398   optab unop = code_to_optab[(int) code];
2399   if (unop == 0)
2400     abort ();
2401
2402   return expand_unop (mode, unop, op0, target, unsignedp);
2403 }
2404
2405 /* Try calculating
2406         (clz:narrow x)
2407    as
2408         (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2409 static rtx
2410 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2411 {
2412   enum mode_class class = GET_MODE_CLASS (mode);
2413   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2414     {
2415       enum machine_mode wider_mode;
2416       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2417            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2418         {
2419           if (clz_optab->handlers[(int) wider_mode].insn_code
2420               != CODE_FOR_nothing)
2421             {
2422               rtx xop0, temp, last;
2423
2424               last = get_last_insn ();
2425
2426               if (target == 0)
2427                 target = gen_reg_rtx (mode);
2428               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2429               temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2430               if (temp != 0)
2431                 temp = expand_binop (wider_mode, sub_optab, temp,
2432                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2433                                               - GET_MODE_BITSIZE (mode)),
2434                                      target, true, OPTAB_DIRECT);
2435               if (temp == 0)
2436                 delete_insns_since (last);
2437
2438               return temp;
2439             }
2440         }
2441     }
2442   return 0;
2443 }
2444
2445 /* Try calculating (parity x) as (and (popcount x) 1), where
2446    popcount can also be done in a wider mode.  */
2447 static rtx
2448 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2449 {
2450   enum mode_class class = GET_MODE_CLASS (mode);
2451   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2452     {
2453       enum machine_mode wider_mode;
2454       for (wider_mode = mode; wider_mode != VOIDmode;
2455            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2456         {
2457           if (popcount_optab->handlers[(int) wider_mode].insn_code
2458               != CODE_FOR_nothing)
2459             {
2460               rtx xop0, temp, last;
2461
2462               last = get_last_insn ();
2463
2464               if (target == 0)
2465                 target = gen_reg_rtx (mode);
2466               xop0 = widen_operand (op0, wider_mode, mode, true, false);
2467               temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2468                                   true);
2469               if (temp != 0)
2470                 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2471                                      target, true, OPTAB_DIRECT);
2472               if (temp == 0)
2473                 delete_insns_since (last);
2474
2475               return temp;
2476             }
2477         }
2478     }
2479   return 0;
2480 }
2481
2482 /* Generate code to perform an operation specified by UNOPTAB
2483    on operand OP0, with result having machine-mode MODE.
2484
2485    UNSIGNEDP is for the case where we have to widen the operands
2486    to perform the operation.  It says to use zero-extension.
2487
2488    If TARGET is nonzero, the value
2489    is generated there, if it is convenient to do so.
2490    In all cases an rtx is returned for the locus of the value;
2491    this may or may not be TARGET.  */
2492
2493 rtx
2494 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2495              int unsignedp)
2496 {
2497   enum mode_class class;
2498   enum machine_mode wider_mode;
2499   rtx temp;
2500   rtx last = get_last_insn ();
2501   rtx pat;
2502
2503   class = GET_MODE_CLASS (mode);
2504
2505   op0 = protect_from_queue (op0, 0);
2506
2507   if (flag_force_mem)
2508     {
2509       op0 = force_not_mem (op0);
2510     }
2511
2512   if (target)
2513     target = protect_from_queue (target, 1);
2514
2515   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2516     {
2517       int icode = (int) unoptab->handlers[(int) mode].insn_code;
2518       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2519       rtx xop0 = op0;
2520
2521       if (target)
2522         temp = target;
2523       else
2524         temp = gen_reg_rtx (mode);
2525
2526       if (GET_MODE (xop0) != VOIDmode
2527           && GET_MODE (xop0) != mode0)
2528         xop0 = convert_to_mode (mode0, xop0, unsignedp);
2529
2530       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
2531
2532       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2533         xop0 = copy_to_mode_reg (mode0, xop0);
2534
2535       if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2536         temp = gen_reg_rtx (mode);
2537
2538       pat = GEN_FCN (icode) (temp, xop0);
2539       if (pat)
2540         {
2541           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2542               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2543             {
2544               delete_insns_since (last);
2545               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2546             }
2547
2548           emit_insn (pat);
2549
2550           return temp;
2551         }
2552       else
2553         delete_insns_since (last);
2554     }
2555
2556   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
2557
2558   /* Widening clz needs special treatment.  */
2559   if (unoptab == clz_optab)
2560     {
2561       temp = widen_clz (mode, op0, target);
2562       if (temp)
2563         return temp;
2564       else
2565         goto try_libcall;
2566     }
2567
2568   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2569     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2570          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2571       {
2572         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2573           {
2574             rtx xop0 = op0;
2575
2576             /* For certain operations, we need not actually extend
2577                the narrow operand, as long as we will truncate the
2578                results to the same narrowness.  */
2579
2580             xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2581                                   (unoptab == neg_optab
2582                                    || unoptab == one_cmpl_optab)
2583                                   && class == MODE_INT);
2584
2585             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2586                                 unsignedp);
2587
2588             if (temp)
2589               {
2590                 if (class != MODE_INT)
2591                   {
2592                     if (target == 0)
2593                       target = gen_reg_rtx (mode);
2594                     convert_move (target, temp, 0);
2595                     return target;
2596                   }
2597                 else
2598                   return gen_lowpart (mode, temp);
2599               }
2600             else
2601               delete_insns_since (last);
2602           }
2603       }
2604
2605   /* These can be done a word at a time.  */
2606   if (unoptab == one_cmpl_optab
2607       && class == MODE_INT
2608       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2609       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2610     {
2611       int i;
2612       rtx insns;
2613
2614       if (target == 0 || target == op0)
2615         target = gen_reg_rtx (mode);
2616
2617       start_sequence ();
2618
2619       /* Do the actual arithmetic.  */
2620       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2621         {
2622           rtx target_piece = operand_subword (target, i, 1, mode);
2623           rtx x = expand_unop (word_mode, unoptab,
2624                                operand_subword_force (op0, i, mode),
2625                                target_piece, unsignedp);
2626
2627           if (target_piece != x)
2628             emit_move_insn (target_piece, x);
2629         }
2630
2631       insns = get_insns ();
2632       end_sequence ();
2633
2634       emit_no_conflict_block (insns, target, op0, NULL_RTX,
2635                               gen_rtx_fmt_e (unoptab->code, mode,
2636                                              copy_rtx (op0)));
2637       return target;
2638     }
2639
2640   /* Open-code the complex negation operation.  */
2641   else if (unoptab->code == NEG
2642            && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2643     {
2644       rtx target_piece;
2645       rtx x;
2646       rtx seq;
2647
2648       /* Find the correct mode for the real and imaginary parts.  */
2649       enum machine_mode submode = GET_MODE_INNER (mode);
2650
2651       if (submode == BLKmode)
2652         abort ();
2653
2654       if (target == 0)
2655         target = gen_reg_rtx (mode);
2656
2657       start_sequence ();
2658
2659       target_piece = gen_imagpart (submode, target);
2660       x = expand_unop (submode, unoptab,
2661                        gen_imagpart (submode, op0),
2662                        target_piece, unsignedp);
2663       if (target_piece != x)
2664         emit_move_insn (target_piece, x);
2665
2666       target_piece = gen_realpart (submode, target);
2667       x = expand_unop (submode, unoptab,
2668                        gen_realpart (submode, op0),
2669                        target_piece, unsignedp);
2670       if (target_piece != x)
2671         emit_move_insn (target_piece, x);
2672
2673       seq = get_insns ();
2674       end_sequence ();
2675
2676       emit_no_conflict_block (seq, target, op0, 0,
2677                               gen_rtx_fmt_e (unoptab->code, mode,
2678                                              copy_rtx (op0)));
2679       return target;
2680     }
2681
2682   /* Try negating floating point values by flipping the sign bit.  */
2683   if (unoptab->code == NEG && class == MODE_FLOAT
2684       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2685     {
2686       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2687       enum machine_mode imode = int_mode_for_mode (mode);
2688       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2689
2690       if (imode != BLKmode && bitpos >= 0 && fmt->has_signed_zero)
2691         {
2692           HOST_WIDE_INT hi, lo;
2693           rtx last = get_last_insn ();
2694
2695           /* Handle targets with different FP word orders.  */
2696           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2697             {
2698               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2699               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2700               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2701             }
2702
2703           if (bitpos < HOST_BITS_PER_WIDE_INT)
2704             {
2705               hi = 0;
2706               lo = (HOST_WIDE_INT) 1 << bitpos;
2707             }
2708           else
2709             {
2710               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2711               lo = 0;
2712             }
2713           temp = expand_binop (imode, xor_optab,
2714                                gen_lowpart (imode, op0),
2715                                immed_double_const (lo, hi, imode),
2716                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2717           if (temp != 0)
2718             {
2719               rtx insn;
2720               if (target == 0)
2721                 target = gen_reg_rtx (mode);
2722               insn = emit_move_insn (target, gen_lowpart (mode, temp));
2723               set_unique_reg_note (insn, REG_EQUAL,
2724                                    gen_rtx_fmt_e (NEG, mode,
2725                                                   copy_rtx (op0)));
2726               return target;
2727             }
2728           delete_insns_since (last);
2729         }
2730     }
2731
2732   /* Try calculating parity (x) as popcount (x) % 2.  */
2733   if (unoptab == parity_optab)
2734     {
2735       temp = expand_parity (mode, op0, target);
2736       if (temp)
2737         return temp;
2738     }
2739
2740   /* If there is no negation pattern, try subtracting from zero.  */
2741   if (unoptab == neg_optab && class == MODE_INT)
2742     {
2743       temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2744                            target, unsignedp, OPTAB_DIRECT);
2745       if (temp)
2746         return temp;
2747     }
2748
2749  try_libcall:
2750   /* Now try a library call in this mode.  */
2751   if (unoptab->handlers[(int) mode].libfunc)
2752     {
2753       rtx insns;
2754       rtx value;
2755       enum machine_mode outmode = mode;
2756
2757       /* All of these functions return small values.  Thus we choose to
2758          have them return something that isn't a double-word.  */
2759       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2760           || unoptab == popcount_optab || unoptab == parity_optab)
2761         outmode
2762             = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2763
2764       start_sequence ();
2765
2766       /* Pass 1 for NO_QUEUE so we don't lose any increments
2767          if the libcall is cse'd or moved.  */
2768       value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2769                                        NULL_RTX, LCT_CONST, outmode,
2770                                        1, op0, mode);
2771       insns = get_insns ();
2772       end_sequence ();
2773
2774       target = gen_reg_rtx (outmode);
2775       emit_libcall_block (insns, target, value,
2776                           gen_rtx_fmt_e (unoptab->code, mode, op0));
2777
2778       return target;
2779     }
2780
2781   if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT)
2782     return expand_vector_unop (mode, unoptab, op0, target, unsignedp);
2783
2784   /* It can't be done in this mode.  Can we do it in a wider mode?  */
2785
2786   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2787     {
2788       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2789            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2790         {
2791           if ((unoptab->handlers[(int) wider_mode].insn_code
2792                != CODE_FOR_nothing)
2793               || unoptab->handlers[(int) wider_mode].libfunc)
2794             {
2795               rtx xop0 = op0;
2796
2797               /* For certain operations, we need not actually extend
2798                  the narrow operand, as long as we will truncate the
2799                  results to the same narrowness.  */
2800
2801               xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2802                                     (unoptab == neg_optab
2803                                      || unoptab == one_cmpl_optab)
2804                                     && class == MODE_INT);
2805
2806               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2807                                   unsignedp);
2808
2809               /* If we are generating clz using wider mode, adjust the
2810                  result.  */
2811               if (unoptab == clz_optab && temp != 0)
2812                 temp = expand_binop (wider_mode, sub_optab, temp,
2813                                      GEN_INT (GET_MODE_BITSIZE (wider_mode)
2814                                               - GET_MODE_BITSIZE (mode)),
2815                                      target, true, OPTAB_DIRECT);
2816
2817               if (temp)
2818                 {
2819                   if (class != MODE_INT)
2820                     {
2821                       if (target == 0)
2822                         target = gen_reg_rtx (mode);
2823                       convert_move (target, temp, 0);
2824                       return target;
2825                     }
2826                   else
2827                     return gen_lowpart (mode, temp);
2828                 }
2829               else
2830                 delete_insns_since (last);
2831             }
2832         }
2833     }
2834
2835   /* If there is no negate operation, try doing a subtract from zero.
2836      The US Software GOFAST library needs this.  */
2837   if (unoptab->code == NEG)
2838     {
2839       rtx temp;
2840       temp = expand_binop (mode,
2841                            unoptab == negv_optab ? subv_optab : sub_optab,
2842                            CONST0_RTX (mode), op0,
2843                            target, unsignedp, OPTAB_LIB_WIDEN);
2844       if (temp)
2845         return temp;
2846     }
2847
2848   return 0;
2849 }
2850 \f
2851 /* Emit code to compute the absolute value of OP0, with result to
2852    TARGET if convenient.  (TARGET may be 0.)  The return value says
2853    where the result actually is to be found.
2854
2855    MODE is the mode of the operand; the mode of the result is
2856    different but can be deduced from MODE.
2857
2858  */
2859
2860 rtx
2861 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2862                    int result_unsignedp)
2863 {
2864   rtx temp;
2865
2866   if (! flag_trapv)
2867     result_unsignedp = 1;
2868
2869   /* First try to do it with a special abs instruction.  */
2870   temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2871                       op0, target, 0);
2872   if (temp != 0)
2873     return temp;
2874
2875   /* For floating point modes, try clearing the sign bit.  */
2876   if (GET_MODE_CLASS (mode) == MODE_FLOAT
2877       && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
2878     {
2879       const struct real_format *fmt = REAL_MODE_FORMAT (mode);
2880       enum machine_mode imode = int_mode_for_mode (mode);
2881       int bitpos = (fmt != 0) ? fmt->signbit : -1;
2882
2883       if (imode != BLKmode && bitpos >= 0)
2884         {
2885           HOST_WIDE_INT hi, lo;
2886           rtx last = get_last_insn ();
2887
2888           /* Handle targets with different FP word orders.  */
2889           if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
2890             {
2891               int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
2892               int word = nwords - (bitpos / BITS_PER_WORD) - 1;
2893               bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
2894             }
2895
2896           if (bitpos < HOST_BITS_PER_WIDE_INT)
2897             {
2898               hi = 0;
2899               lo = (HOST_WIDE_INT) 1 << bitpos;
2900             }
2901           else
2902             {
2903               hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2904               lo = 0;
2905             }
2906           temp = expand_binop (imode, and_optab,
2907                                gen_lowpart (imode, op0),
2908                                immed_double_const (~lo, ~hi, imode),
2909                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
2910           if (temp != 0)
2911             {
2912               rtx insn;
2913               if (target == 0)
2914                 target = gen_reg_rtx (mode);
2915               insn = emit_move_insn (target, gen_lowpart (mode, temp));
2916               set_unique_reg_note (insn, REG_EQUAL,
2917                                    gen_rtx_fmt_e (ABS, mode,
2918                                                   copy_rtx (op0)));
2919               return target;
2920             }
2921           delete_insns_since (last);
2922         }
2923     }
2924
2925   /* If we have a MAX insn, we can do this as MAX (x, -x).  */
2926   if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2927     {
2928       rtx last = get_last_insn ();
2929
2930       temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2931       if (temp != 0)
2932         temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2933                              OPTAB_WIDEN);
2934
2935       if (temp != 0)
2936         return temp;
2937
2938       delete_insns_since (last);
2939     }
2940
2941   /* If this machine has expensive jumps, we can do integer absolute
2942      value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2943      where W is the width of MODE.  */
2944
2945   if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2946     {
2947       rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2948                                    size_int (GET_MODE_BITSIZE (mode) - 1),
2949                                    NULL_RTX, 0);
2950
2951       temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2952                            OPTAB_LIB_WIDEN);
2953       if (temp != 0)
2954         temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2955                              temp, extended, target, 0, OPTAB_LIB_WIDEN);
2956
2957       if (temp != 0)
2958         return temp;
2959     }
2960
2961   return NULL_RTX;
2962 }
2963
2964 rtx
2965 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2966             int result_unsignedp, int safe)
2967 {
2968   rtx temp, op1;
2969
2970   if (! flag_trapv)
2971     result_unsignedp = 1;
2972
2973   temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2974   if (temp != 0)
2975     return temp;
2976
2977   /* If that does not win, use conditional jump and negate.  */
2978
2979   /* It is safe to use the target if it is the same
2980      as the source if this is also a pseudo register */
2981   if (op0 == target && GET_CODE (op0) == REG
2982       && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2983     safe = 1;
2984
2985   op1 = gen_label_rtx ();
2986   if (target == 0 || ! safe
2987       || GET_MODE (target) != mode
2988       || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2989       || (GET_CODE (target) == REG
2990           && REGNO (target) < FIRST_PSEUDO_REGISTER))
2991     target = gen_reg_rtx (mode);
2992
2993   emit_move_insn (target, op0);
2994   NO_DEFER_POP;
2995
2996   /* If this mode is an integer too wide to compare properly,
2997      compare word by word.  Rely on CSE to optimize constant cases.  */
2998   if (GET_MODE_CLASS (mode) == MODE_INT
2999       && ! can_compare_p (GE, mode, ccp_jump))
3000     do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
3001                                   NULL_RTX, op1);
3002   else
3003     do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3004                              NULL_RTX, NULL_RTX, op1);
3005
3006   op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3007                      target, target, 0);
3008   if (op0 != target)
3009     emit_move_insn (target, op0);
3010   emit_label (op1);
3011   OK_DEFER_POP;
3012   return target;
3013 }
3014 \f
3015 /* Emit code to compute the absolute value of OP0, with result to
3016    TARGET if convenient.  (TARGET may be 0.)  The return value says
3017    where the result actually is to be found.
3018
3019    MODE is the mode of the operand; the mode of the result is
3020    different but can be deduced from MODE.
3021
3022    UNSIGNEDP is relevant for complex integer modes.  */
3023
3024 rtx
3025 expand_complex_abs (enum machine_mode mode, rtx op0, rtx target,
3026                     int unsignedp)
3027 {
3028   enum mode_class class = GET_MODE_CLASS (mode);
3029   enum machine_mode wider_mode;
3030   rtx temp;
3031   rtx entry_last = get_last_insn ();
3032   rtx last;
3033   rtx pat;
3034   optab this_abs_optab;
3035
3036   /* Find the correct mode for the real and imaginary parts.  */
3037   enum machine_mode submode = GET_MODE_INNER (mode);
3038
3039   if (submode == BLKmode)
3040     abort ();
3041
3042   op0 = protect_from_queue (op0, 0);
3043
3044   if (flag_force_mem)
3045     {
3046       op0 = force_not_mem (op0);
3047     }
3048
3049   last = get_last_insn ();
3050
3051   if (target)
3052     target = protect_from_queue (target, 1);
3053
3054   this_abs_optab = ! unsignedp && flag_trapv
3055                    && (GET_MODE_CLASS(mode) == MODE_INT)
3056                    ? absv_optab : abs_optab;
3057
3058   if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3059     {
3060       int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
3061       enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3062       rtx xop0 = op0;
3063
3064       if (target)
3065         temp = target;
3066       else
3067         temp = gen_reg_rtx (submode);
3068
3069       if (GET_MODE (xop0) != VOIDmode
3070           && GET_MODE (xop0) != mode0)
3071         xop0 = convert_to_mode (mode0, xop0, unsignedp);
3072
3073       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
3074
3075       if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
3076         xop0 = copy_to_mode_reg (mode0, xop0);
3077
3078       if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
3079         temp = gen_reg_rtx (submode);
3080
3081       pat = GEN_FCN (icode) (temp, xop0);
3082       if (pat)
3083         {
3084           if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3085               && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
3086                                    NULL_RTX))
3087             {
3088               delete_insns_since (last);
3089               return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
3090                                   unsignedp);
3091             }
3092
3093           emit_insn (pat);
3094
3095           return temp;
3096         }
3097       else
3098         delete_insns_since (last);
3099     }
3100
3101   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
3102
3103   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3104        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3105     {
3106       if (this_abs_optab->handlers[(int) wider_mode].insn_code
3107           != CODE_FOR_nothing)
3108         {
3109           rtx xop0 = op0;
3110
3111           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3112           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3113
3114           if (temp)
3115             {
3116               if (class != MODE_COMPLEX_INT)
3117                 {
3118                   if (target == 0)
3119                     target = gen_reg_rtx (submode);
3120                   convert_move (target, temp, 0);
3121                   return target;
3122                 }
3123               else
3124                 return gen_lowpart (submode, temp);
3125             }
3126           else
3127             delete_insns_since (last);
3128         }
3129     }
3130
3131   /* Open-code the complex absolute-value operation
3132      if we can open-code sqrt.  Otherwise it's not worth while.  */
3133   if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
3134       && ! flag_trapv)
3135     {
3136       rtx real, imag, total;
3137
3138       real = gen_realpart (submode, op0);
3139       imag = gen_imagpart (submode, op0);
3140
3141       /* Square both parts.  */
3142       real = expand_mult (submode, real, real, NULL_RTX, 0);
3143       imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
3144
3145       /* Sum the parts.  */
3146       total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
3147                             0, OPTAB_LIB_WIDEN);
3148
3149       /* Get sqrt in TARGET.  Set TARGET to where the result is.  */
3150       target = expand_unop (submode, sqrt_optab, total, target, 0);
3151       if (target == 0)
3152         delete_insns_since (last);
3153       else
3154         return target;
3155     }
3156
3157   /* Now try a library call in this mode.  */
3158   if (this_abs_optab->handlers[(int) mode].libfunc)
3159     {
3160       rtx insns;
3161       rtx value;
3162
3163       start_sequence ();
3164
3165       /* Pass 1 for NO_QUEUE so we don't lose any increments
3166          if the libcall is cse'd or moved.  */
3167       value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
3168                                        NULL_RTX, LCT_CONST, submode, 1, op0, mode);
3169       insns = get_insns ();
3170       end_sequence ();
3171
3172       target = gen_reg_rtx (submode);
3173       emit_libcall_block (insns, target, value,
3174                           gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
3175
3176       return target;
3177     }
3178
3179   /* It can't be done in this mode.  Can we do it in a wider mode?  */
3180
3181   for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3182        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3183     {
3184       if ((this_abs_optab->handlers[(int) wider_mode].insn_code
3185            != CODE_FOR_nothing)
3186           || this_abs_optab->handlers[(int) wider_mode].libfunc)
3187         {
3188           rtx xop0 = op0;
3189
3190           xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
3191
3192           temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
3193
3194           if (temp)
3195             {
3196               if (class != MODE_COMPLEX_INT)
3197                 {
3198                   if (target == 0)
3199                     target = gen_reg_rtx (submode);
3200                   convert_move (target, temp, 0);
3201                   return target;
3202                 }
3203               else
3204                 return gen_lowpart (submode, temp);
3205             }
3206           else
3207             delete_insns_since (last);
3208         }
3209     }
3210
3211   delete_insns_since (entry_last);
3212   return 0;
3213 }
3214 \f
3215 /* Generate an instruction whose insn-code is INSN_CODE,
3216    with two operands: an output TARGET and an input OP0.
3217    TARGET *must* be nonzero, and the output is always stored there.
3218    CODE is an rtx code such that (CODE OP0) is an rtx that describes
3219    the value that is stored into TARGET.  */
3220
3221 void
3222 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3223 {
3224   rtx temp;
3225   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3226   rtx pat;
3227
3228   temp = target = protect_from_queue (target, 1);
3229
3230   op0 = protect_from_queue (op0, 0);
3231
3232   /* Sign and zero extension from memory is often done specially on
3233      RISC machines, so forcing into a register here can pessimize
3234      code.  */
3235   if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
3236     op0 = force_not_mem (op0);
3237
3238   /* Now, if insn does not accept our operands, put them into pseudos.  */
3239
3240   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3241     op0 = copy_to_mode_reg (mode0, op0);
3242
3243   if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
3244       || (flag_force_mem && GET_CODE (temp) == MEM))
3245     temp = gen_reg_rtx (GET_MODE (temp));
3246
3247   pat = GEN_FCN (icode) (temp, op0);
3248
3249   if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3250     add_equal_note (pat, temp, code, op0, NULL_RTX);
3251
3252   emit_insn (pat);
3253
3254   if (temp != target)
3255     emit_move_insn (target, temp);
3256 }
3257 \f
3258 /* Emit code to perform a series of operations on a multi-word quantity, one
3259    word at a time.
3260
3261    Such a block is preceded by a CLOBBER of the output, consists of multiple
3262    insns, each setting one word of the output, and followed by a SET copying
3263    the output to itself.
3264
3265    Each of the insns setting words of the output receives a REG_NO_CONFLICT
3266    note indicating that it doesn't conflict with the (also multi-word)
3267    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3268    notes.
3269
3270    INSNS is a block of code generated to perform the operation, not including
3271    the CLOBBER and final copy.  All insns that compute intermediate values
3272    are first emitted, followed by the block as described above.
3273
3274    TARGET, OP0, and OP1 are the output and inputs of the operations,
3275    respectively.  OP1 may be zero for a unary operation.
3276
3277    EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3278    on the last insn.
3279
3280    If TARGET is not a register, INSNS is simply emitted with no special
3281    processing.  Likewise if anything in INSNS is not an INSN or if
3282    there is a libcall block inside INSNS.
3283
3284    The final insn emitted is returned.  */
3285
3286 rtx
3287 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3288 {
3289   rtx prev, next, first, last, insn;
3290
3291   if (GET_CODE (target) != REG || reload_in_progress)
3292     return emit_insn (insns);
3293   else
3294     for (insn = insns; insn; insn = NEXT_INSN (insn))
3295       if (GET_CODE (insn) != INSN
3296           || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3297         return emit_insn (insns);
3298
3299   /* First emit all insns that do not store into words of the output and remove
3300      these from the list.  */
3301   for (insn = insns; insn; insn = next)
3302     {
3303       rtx set = 0, note;
3304       int i;
3305
3306       next = NEXT_INSN (insn);
3307
3308       /* Some ports (cris) create a libcall regions at their own.  We must
3309          avoid any potential nesting of LIBCALLs.  */
3310       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3311         remove_note (insn, note);
3312       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3313         remove_note (insn, note);
3314
3315       if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3316           || GET_CODE (PATTERN (insn)) == CLOBBER)
3317         set = PATTERN (insn);
3318       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3319         {
3320           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3321             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3322               {
3323                 set = XVECEXP (PATTERN (insn), 0, i);
3324                 break;
3325               }
3326         }
3327
3328       if (set == 0)
3329         abort ();
3330
3331       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3332         {
3333           if (PREV_INSN (insn))
3334             NEXT_INSN (PREV_INSN (insn)) = next;
3335           else
3336             insns = next;
3337
3338           if (next)
3339             PREV_INSN (next) = PREV_INSN (insn);
3340
3341           add_insn (insn);
3342         }
3343     }
3344
3345   prev = get_last_insn ();
3346
3347   /* Now write the CLOBBER of the output, followed by the setting of each
3348      of the words, followed by the final copy.  */
3349   if (target != op0 && target != op1)
3350     emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3351
3352   for (insn = insns; insn; insn = next)
3353     {
3354       next = NEXT_INSN (insn);
3355       add_insn (insn);
3356
3357       if (op1 && GET_CODE (op1) == REG)
3358         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3359                                               REG_NOTES (insn));
3360
3361       if (op0 && GET_CODE (op0) == REG)
3362         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3363                                               REG_NOTES (insn));
3364     }
3365
3366   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3367       != CODE_FOR_nothing)
3368     {
3369       last = emit_move_insn (target, target);
3370       if (equiv)
3371         set_unique_reg_note (last, REG_EQUAL, equiv);
3372     }
3373   else
3374     {
3375       last = get_last_insn ();
3376
3377       /* Remove any existing REG_EQUAL note from "last", or else it will
3378          be mistaken for a note referring to the full contents of the
3379          alleged libcall value when found together with the REG_RETVAL
3380          note added below.  An existing note can come from an insn
3381          expansion at "last".  */
3382       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3383     }
3384
3385   if (prev == 0)
3386     first = get_insns ();
3387   else
3388     first = NEXT_INSN (prev);
3389
3390   /* Encapsulate the block so it gets manipulated as a unit.  */
3391   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3392                                          REG_NOTES (first));
3393   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3394
3395   return last;
3396 }
3397 \f
3398 /* Emit code to make a call to a constant function or a library call.
3399
3400    INSNS is a list containing all insns emitted in the call.
3401    These insns leave the result in RESULT.  Our block is to copy RESULT
3402    to TARGET, which is logically equivalent to EQUIV.
3403
3404    We first emit any insns that set a pseudo on the assumption that these are
3405    loading constants into registers; doing so allows them to be safely cse'ed
3406    between blocks.  Then we emit all the other insns in the block, followed by
3407    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3408    note with an operand of EQUIV.
3409
3410    Moving assignments to pseudos outside of the block is done to improve
3411    the generated code, but is not required to generate correct code,
3412    hence being unable to move an assignment is not grounds for not making
3413    a libcall block.  There are two reasons why it is safe to leave these
3414    insns inside the block: First, we know that these pseudos cannot be
3415    used in generated RTL outside the block since they are created for
3416    temporary purposes within the block.  Second, CSE will not record the
3417    values of anything set inside a libcall block, so we know they must
3418    be dead at the end of the block.
3419
3420    Except for the first group of insns (the ones setting pseudos), the
3421    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
3422
3423 void
3424 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3425 {
3426   rtx final_dest = target;
3427   rtx prev, next, first, last, insn;
3428
3429   /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3430      into a MEM later.  Protect the libcall block from this change.  */
3431   if (! REG_P (target) || REG_USERVAR_P (target))
3432     target = gen_reg_rtx (GET_MODE (target));
3433
3434   /* If we're using non-call exceptions, a libcall corresponding to an
3435      operation that may trap may also trap.  */
3436   if (flag_non_call_exceptions && may_trap_p (equiv))
3437     {
3438       for (insn = insns; insn; insn = NEXT_INSN (insn))
3439         if (GET_CODE (insn) == CALL_INSN)
3440           {
3441             rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3442
3443             if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3444               remove_note (insn, note);
3445           }
3446     }
3447   else
3448   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3449      reg note to indicate that this call cannot throw or execute a nonlocal
3450      goto (unless there is already a REG_EH_REGION note, in which case
3451      we update it).  */
3452     for (insn = insns; insn; insn = NEXT_INSN (insn))
3453       if (GET_CODE (insn) == CALL_INSN)
3454         {
3455           rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3456
3457           if (note != 0)
3458             XEXP (note, 0) = constm1_rtx;
3459           else
3460             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3461                                                   REG_NOTES (insn));
3462         }
3463
3464   /* First emit all insns that set pseudos.  Remove them from the list as
3465      we go.  Avoid insns that set pseudos which were referenced in previous
3466      insns.  These can be generated by move_by_pieces, for example,
3467      to update an address.  Similarly, avoid insns that reference things
3468      set in previous insns.  */
3469
3470   for (insn = insns; insn; insn = next)
3471     {
3472       rtx set = single_set (insn);
3473       rtx note;
3474
3475       /* Some ports (cris) create a libcall regions at their own.  We must
3476          avoid any potential nesting of LIBCALLs.  */
3477       if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3478         remove_note (insn, note);
3479       if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3480         remove_note (insn, note);
3481
3482       next = NEXT_INSN (insn);
3483
3484       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
3485           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3486           && (insn == insns
3487               || ((! INSN_P(insns)
3488                    || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3489                   && ! reg_used_between_p (SET_DEST (set), insns, insn)
3490                   && ! modified_in_p (SET_SRC (set), insns)
3491                   && ! modified_between_p (SET_SRC (set), insns, insn))))
3492         {
3493           if (PREV_INSN (insn))
3494             NEXT_INSN (PREV_INSN (insn)) = next;
3495           else
3496             insns = next;
3497
3498           if (next)
3499             PREV_INSN (next) = PREV_INSN (insn);
3500
3501           add_insn (insn);
3502         }
3503
3504       /* Some ports use a loop to copy large arguments onto the stack.
3505          Don't move anything outside such a loop.  */
3506       if (GET_CODE (insn) == CODE_LABEL)
3507         break;
3508     }
3509
3510   prev = get_last_insn ();
3511
3512   /* Write the remaining insns followed by the final copy.  */
3513
3514   for (insn = insns; insn; insn = next)
3515     {
3516       next = NEXT_INSN (insn);
3517
3518       add_insn (insn);
3519     }
3520
3521   last = emit_move_insn (target, result);
3522   if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3523       != CODE_FOR_nothing)
3524     set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3525   else
3526     {
3527       /* Remove any existing REG_EQUAL note from "last", or else it will
3528          be mistaken for a note referring to the full contents of the
3529          libcall value when found together with the REG_RETVAL note added
3530          below.  An existing note can come from an insn expansion at
3531          "last".  */
3532       remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3533     }
3534
3535   if (final_dest != target)
3536     emit_move_insn (final_dest, target);
3537
3538   if (prev == 0)
3539     first = get_insns ();
3540   else
3541     first = NEXT_INSN (prev);
3542
3543   /* Encapsulate the block so it gets manipulated as a unit.  */
3544   if (!flag_non_call_exceptions || !may_trap_p (equiv))
3545     {
3546       /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3547          when the encapsulated region would not be in one basic block,
3548          i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3549        */
3550       bool attach_libcall_retval_notes = true;
3551       next = NEXT_INSN (last);
3552       for (insn = first; insn != next; insn = NEXT_INSN (insn))
3553         if (control_flow_insn_p (insn))
3554           {
3555             attach_libcall_retval_notes = false;
3556             break;
3557           }
3558
3559       if (attach_libcall_retval_notes)
3560         {
3561           REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3562                                                  REG_NOTES (first));
3563           REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3564                                                 REG_NOTES (last));
3565         }
3566     }
3567 }
3568 \f
3569 /* Generate code to store zero in X.  */
3570
3571 void
3572 emit_clr_insn (rtx x)
3573 {
3574   emit_move_insn (x, const0_rtx);
3575 }
3576
3577 /* Generate code to store 1 in X
3578    assuming it contains zero beforehand.  */
3579
3580 void
3581 emit_0_to_1_insn (rtx x)
3582 {
3583   emit_move_insn (x, const1_rtx);
3584 }
3585
3586 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3587    PURPOSE describes how this comparison will be used.  CODE is the rtx
3588    comparison code we will be using.
3589
3590    ??? Actually, CODE is slightly weaker than that.  A target is still
3591    required to implement all of the normal bcc operations, but not
3592    required to implement all (or any) of the unordered bcc operations.  */
3593
3594 int
3595 can_compare_p (enum rtx_code code, enum machine_mode mode,
3596                enum can_compare_purpose purpose)
3597 {
3598   do
3599     {
3600       if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3601         {
3602           if (purpose == ccp_jump)
3603             return bcc_gen_fctn[(int) code] != NULL;
3604           else if (purpose == ccp_store_flag)
3605             return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3606           else
3607             /* There's only one cmov entry point, and it's allowed to fail.  */
3608             return 1;
3609         }
3610       if (purpose == ccp_jump
3611           && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3612         return 1;
3613       if (purpose == ccp_cmov
3614           && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3615         return 1;
3616       if (purpose == ccp_store_flag
3617           && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3618         return 1;
3619
3620       mode = GET_MODE_WIDER_MODE (mode);
3621     }
3622   while (mode != VOIDmode);
3623
3624   return 0;
3625 }
3626
3627 /* This function is called when we are going to emit a compare instruction that
3628    compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3629
3630    *PMODE is the mode of the inputs (in case they are const_int).
3631    *PUNSIGNEDP nonzero says that the operands are unsigned;
3632    this matters if they need to be widened.
3633
3634    If they have mode BLKmode, then SIZE specifies the size of both operands.
3635
3636    This function performs all the setup necessary so that the caller only has
3637    to emit a single comparison insn.  This setup can involve doing a BLKmode
3638    comparison or emitting a library call to perform the comparison if no insn
3639    is available to handle it.
3640    The values which are passed in through pointers can be modified; the caller
3641    should perform the comparison on the modified values.  */
3642
3643 static void
3644 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3645                   enum machine_mode *pmode, int *punsignedp,
3646                   enum can_compare_purpose purpose)
3647 {
3648   enum machine_mode mode = *pmode;
3649   rtx x = *px, y = *py;
3650   int unsignedp = *punsignedp;
3651   enum mode_class class;
3652
3653   class = GET_MODE_CLASS (mode);
3654
3655   /* They could both be VOIDmode if both args are immediate constants,
3656      but we should fold that at an earlier stage.
3657      With no special code here, this will call abort,
3658      reminding the programmer to implement such folding.  */
3659
3660   if (mode != BLKmode && flag_force_mem)
3661     {
3662       /* Load duplicate non-volatile operands once.  */
3663       if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
3664         {
3665           x = force_not_mem (x);
3666           y = x;
3667         }
3668       else
3669         {
3670           x = force_not_mem (x);
3671           y = force_not_mem (y);
3672         }
3673     }
3674
3675   /* If we are inside an appropriately-short loop and one operand is an
3676      expensive constant, force it into a register.  */
3677   if (CONSTANT_P (x) && preserve_subexpressions_p ()
3678       && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3679     x = force_reg (mode, x);
3680
3681   if (CONSTANT_P (y) && preserve_subexpressions_p ()
3682       && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3683     y = force_reg (mode, y);
3684
3685 #ifdef HAVE_cc0
3686   /* Abort if we have a non-canonical comparison.  The RTL documentation
3687      states that canonical comparisons are required only for targets which
3688      have cc0.  */
3689   if (CONSTANT_P (x) && ! CONSTANT_P (y))
3690     abort ();
3691 #endif
3692
3693   /* Don't let both operands fail to indicate the mode.  */
3694   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3695     x = force_reg (mode, x);
3696
3697   /* Handle all BLKmode compares.  */
3698
3699   if (mode == BLKmode)
3700     {
3701       enum machine_mode cmp_mode, result_mode;
3702       enum insn_code cmp_code;
3703       tree length_type;
3704       rtx libfunc;
3705       rtx result;
3706       rtx opalign
3707         = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3708
3709       if (size == 0)
3710         abort ();
3711
3712       emit_queue ();
3713       x = protect_from_queue (x, 0);
3714       y = protect_from_queue (y, 0);
3715       size = protect_from_queue (size, 0);
3716
3717       /* Try to use a memory block compare insn - either cmpstr
3718          or cmpmem will do.  */
3719       for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3720            cmp_mode != VOIDmode;
3721            cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3722         {
3723           cmp_code = cmpmem_optab[cmp_mode];
3724           if (cmp_code == CODE_FOR_nothing)
3725             cmp_code = cmpstr_optab[cmp_mode];
3726           if (cmp_code == CODE_FOR_nothing)
3727             continue;
3728
3729           /* Must make sure the size fits the insn's mode.  */
3730           if ((GET_CODE (size) == CONST_INT
3731                && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3732               || (GET_MODE_BITSIZE (GET_MODE (size))
3733                   > GET_MODE_BITSIZE (cmp_mode)))
3734             continue;
3735
3736           result_mode = insn_data[cmp_code].operand[0].mode;
3737           result = gen_reg_rtx (result_mode);
3738           size = convert_to_mode (cmp_mode, size, 1);
3739           emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3740
3741           *px = result;
3742           *py = const0_rtx;
3743           *pmode = result_mode;
3744           return;
3745         }
3746
3747       /* Otherwise call a library function, memcmp if we've got it,
3748          bcmp otherwise.  */
3749 #ifdef TARGET_MEM_FUNCTIONS
3750       libfunc = memcmp_libfunc;
3751       length_type = sizetype;
3752 #else
3753       libfunc = bcmp_libfunc;
3754       length_type = integer_type_node;
3755 #endif
3756       result_mode = TYPE_MODE (integer_type_node);
3757       cmp_mode = TYPE_MODE (length_type);
3758       size = convert_to_mode (TYPE_MODE (length_type), size,
3759                               TYPE_UNSIGNED (length_type));
3760
3761       result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3762                                         result_mode, 3,
3763                                         XEXP (x, 0), Pmode,
3764                                         XEXP (y, 0), Pmode,
3765                                         size, cmp_mode);
3766       *px = result;
3767       *py = const0_rtx;
3768       *pmode = result_mode;
3769       return;
3770     }
3771
3772   /* Don't allow operands to the compare to trap, as that can put the
3773      compare and branch in different basic blocks.  */
3774   if (flag_non_call_exceptions)
3775     {
3776       if (may_trap_p (x))
3777         x = force_reg (mode, x);
3778       if (may_trap_p (y))
3779         y = force_reg (mode, y);
3780     }
3781
3782   *px = x;
3783   *py = y;
3784   if (can_compare_p (*pcomparison, mode, purpose))
3785     return;
3786
3787   /* Handle a lib call just for the mode we are using.  */
3788
3789   if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3790     {
3791       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3792       rtx result;
3793
3794       /* If we want unsigned, and this mode has a distinct unsigned
3795          comparison routine, use that.  */
3796       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3797         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3798
3799       result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3800                                         word_mode, 2, x, mode, y, mode);
3801
3802       /* Integer comparison returns a result that must be compared against 1,
3803          so that even if we do an unsigned compare afterward,
3804          there is still a value that can represent the result "less than".  */
3805       *px = result;
3806       *py = const1_rtx;
3807       *pmode = word_mode;
3808       return;
3809     }
3810
3811   if (class == MODE_FLOAT)
3812     prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3813
3814   else
3815     abort ();
3816 }
3817
3818 /* Before emitting an insn with code ICODE, make sure that X, which is going
3819    to be used for operand OPNUM of the insn, is converted from mode MODE to
3820    WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3821    that it is accepted by the operand predicate.  Return the new value.  */
3822
3823 rtx
3824 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3825                  enum machine_mode wider_mode, int unsignedp)
3826 {
3827   x = protect_from_queue (x, 0);
3828
3829   if (mode != wider_mode)
3830     x = convert_modes (wider_mode, mode, x, unsignedp);
3831
3832   if (! (*insn_data[icode].operand[opnum].predicate)
3833       (x, insn_data[icode].operand[opnum].mode))
3834     {
3835       if (no_new_pseudos)
3836         return NULL_RTX;
3837       x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3838     }
3839
3840   return x;
3841 }
3842
3843 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3844    we can do the comparison.
3845    The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3846    be NULL_RTX which indicates that only a comparison is to be generated.  */
3847
3848 static void
3849 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3850                           enum rtx_code comparison, int unsignedp, rtx label)
3851 {
3852   rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3853   enum mode_class class = GET_MODE_CLASS (mode);
3854   enum machine_mode wider_mode = mode;
3855
3856   /* Try combined insns first.  */
3857   do
3858     {
3859       enum insn_code icode;
3860       PUT_MODE (test, wider_mode);
3861
3862       if (label)
3863         {
3864           icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3865
3866           if (icode != CODE_FOR_nothing
3867               && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3868             {
3869               x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3870               y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3871               emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3872               return;
3873             }
3874         }
3875
3876       /* Handle some compares against zero.  */
3877       icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3878       if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3879         {
3880           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3881           emit_insn (GEN_FCN (icode) (x));
3882           if (label)
3883             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3884           return;
3885         }
3886
3887       /* Handle compares for which there is a directly suitable insn.  */
3888
3889       icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3890       if (icode != CODE_FOR_nothing)
3891         {
3892           x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3893           y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3894           emit_insn (GEN_FCN (icode) (x, y));
3895           if (label)
3896             emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3897           return;
3898         }
3899
3900       if (class != MODE_INT && class != MODE_FLOAT
3901           && class != MODE_COMPLEX_FLOAT)
3902         break;
3903
3904       wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3905     }
3906   while (wider_mode != VOIDmode);
3907
3908   abort ();
3909 }
3910
3911 /* Generate code to compare X with Y so that the condition codes are
3912    set and to jump to LABEL if the condition is true.  If X is a
3913    constant and Y is not a constant, then the comparison is swapped to
3914    ensure that the comparison RTL has the canonical form.
3915
3916    UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3917    need to be widened by emit_cmp_insn.  UNSIGNEDP is also used to select
3918    the proper branch condition code.
3919
3920    If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3921
3922    MODE is the mode of the inputs (in case they are const_int).
3923
3924    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  It will
3925    be passed unchanged to emit_cmp_insn, then potentially converted into an
3926    unsigned variant based on UNSIGNEDP to select a proper jump instruction.  */
3927
3928 void
3929 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3930                          enum machine_mode mode, int unsignedp, rtx label)
3931 {
3932   rtx op0 = x, op1 = y;
3933
3934   /* Swap operands and condition to ensure canonical RTL.  */
3935   if (swap_commutative_operands_p (x, y))
3936     {
3937       /* If we're not emitting a branch, this means some caller
3938          is out of sync.  */
3939       if (! label)
3940         abort ();
3941
3942       op0 = y, op1 = x;
3943       comparison = swap_condition (comparison);
3944     }
3945
3946 #ifdef HAVE_cc0
3947   /* If OP0 is still a constant, then both X and Y must be constants.  Force
3948      X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3949      RTL.  */
3950   if (CONSTANT_P (op0))
3951     op0 = force_reg (mode, op0);
3952 #endif
3953
3954   emit_queue ();
3955   if (unsignedp)
3956     comparison = unsigned_condition (comparison);
3957
3958   prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3959                     ccp_jump);
3960   emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3961 }
3962
3963 /* Like emit_cmp_and_jump_insns, but generate only the comparison.  */
3964
3965 void
3966 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3967                enum machine_mode mode, int unsignedp)
3968 {
3969   emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3970 }
3971 \f
3972 /* Emit a library call comparison between floating point X and Y.
3973    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
3974
3975 static void
3976 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3977                        enum machine_mode *pmode, int *punsignedp)
3978 {
3979   enum rtx_code comparison = *pcomparison;
3980   enum rtx_code swapped = swap_condition (comparison);
3981   rtx x = protect_from_queue (*px, 0);
3982   rtx y = protect_from_queue (*py, 0);
3983   enum machine_mode orig_mode = GET_MODE (x);
3984   enum machine_mode mode;
3985   rtx value, target, insns, equiv;
3986   rtx libfunc = 0;
3987
3988   for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
3989     {
3990       if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3991         break;
3992
3993       if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3994         {
3995           rtx tmp;
3996           tmp = x; x = y; y = tmp;
3997           comparison = swapped;
3998           break;
3999         }
4000     }
4001
4002   if (mode == VOIDmode)
4003     abort ();
4004
4005   if (mode != orig_mode)
4006     {
4007       x = convert_to_mode (mode, x, 0);
4008       y = convert_to_mode (mode, y, 0);
4009     }
4010
4011   /* Attach a REG_EQUAL note describing the semantics of the libcall to
4012      the RTL.  The allows the RTL optimizers to delete the libcall if the
4013      condition can be determined at compile-time.  */
4014   if (comparison == UNORDERED)
4015     {
4016       rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
4017       equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
4018       equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
4019                                     temp, const_true_rtx, equiv);
4020     }
4021   else
4022     {
4023       equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
4024       if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4025         {
4026           rtx true_rtx, false_rtx;
4027
4028           switch (comparison)
4029             {
4030             case EQ:
4031               true_rtx = const0_rtx;
4032               false_rtx = const_true_rtx;
4033               break;
4034
4035             case NE:
4036               true_rtx = const_true_rtx;
4037               false_rtx = const0_rtx;
4038               break;
4039
4040             case GT:
4041               true_rtx = const1_rtx;
4042               false_rtx = const0_rtx;
4043               break;
4044
4045             case GE:
4046               true_rtx = const0_rtx;
4047               false_rtx = constm1_rtx;
4048               break;
4049
4050             case LT:
4051               true_rtx = constm1_rtx;
4052               false_rtx = const0_rtx;
4053               break;
4054
4055             case LE:
4056               true_rtx = const0_rtx;
4057               false_rtx = const1_rtx;
4058               break;
4059
4060             default:
4061               abort ();
4062             }
4063           equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
4064                                         equiv, true_rtx, false_rtx);
4065         }
4066     }
4067
4068   start_sequence ();
4069   value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4070                                    word_mode, 2, x, mode, y, mode);
4071   insns = get_insns ();
4072   end_sequence ();
4073
4074   target = gen_reg_rtx (word_mode);
4075   emit_libcall_block (insns, target, value, equiv);
4076
4077
4078   if (comparison == UNORDERED
4079       || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4080     comparison = NE;
4081
4082   *px = target;
4083   *py = const0_rtx;
4084   *pmode = word_mode;
4085   *pcomparison = comparison;
4086   *punsignedp = 0;
4087 }
4088 \f
4089 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
4090
4091 void
4092 emit_indirect_jump (rtx loc)
4093 {
4094   if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
4095          (loc, Pmode)))
4096     loc = copy_to_mode_reg (Pmode, loc);
4097
4098   emit_jump_insn (gen_indirect_jump (loc));
4099   emit_barrier ();
4100 }
4101 \f
4102 #ifdef HAVE_conditional_move
4103
4104 /* Emit a conditional move instruction if the machine supports one for that
4105    condition and machine mode.
4106
4107    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4108    the mode to use should they be constants.  If it is VOIDmode, they cannot
4109    both be constants.
4110
4111    OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4112    should be stored there.  MODE is the mode to use should they be constants.
4113    If it is VOIDmode, they cannot both be constants.
4114
4115    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4116    is not supported.  */
4117
4118 rtx
4119 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4120                        enum machine_mode cmode, rtx op2, rtx op3,
4121                        enum machine_mode mode, int unsignedp)
4122 {
4123   rtx tem, subtarget, comparison, insn;
4124   enum insn_code icode;
4125   enum rtx_code reversed;
4126
4127   /* If one operand is constant, make it the second one.  Only do this
4128      if the other operand is not constant as well.  */
4129
4130   if (swap_commutative_operands_p (op0, op1))
4131     {
4132       tem = op0;
4133       op0 = op1;
4134       op1 = tem;
4135       code = swap_condition (code);
4136     }
4137
4138   /* get_condition will prefer to generate LT and GT even if the old
4139      comparison was against zero, so undo that canonicalization here since
4140      comparisons against zero are cheaper.  */
4141   if (code == LT && op1 == const1_rtx)
4142     code = LE, op1 = const0_rtx;
4143   else if (code == GT && op1 == constm1_rtx)
4144     code = GE, op1 = const0_rtx;
4145
4146   if (cmode == VOIDmode)
4147     cmode = GET_MODE (op0);
4148
4149   if (swap_commutative_operands_p (op2, op3)
4150       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4151           != UNKNOWN))
4152     {
4153       tem = op2;
4154       op2 = op3;
4155       op3 = tem;
4156       code = reversed;
4157     }
4158
4159   if (mode == VOIDmode)
4160     mode = GET_MODE (op2);
4161
4162   icode = movcc_gen_code[mode];
4163
4164   if (icode == CODE_FOR_nothing)
4165     return 0;
4166
4167   if (flag_force_mem)
4168     {
4169       op2 = force_not_mem (op2);
4170       op3 = force_not_mem (op3);
4171     }
4172
4173   if (target)
4174     target = protect_from_queue (target, 1);
4175   else
4176     target = gen_reg_rtx (mode);
4177
4178   subtarget = target;
4179
4180   emit_queue ();
4181
4182   op2 = protect_from_queue (op2, 0);
4183   op3 = protect_from_queue (op3, 0);
4184
4185   /* If the insn doesn't accept these operands, put them in pseudos.  */
4186
4187   if (! (*insn_data[icode].operand[0].predicate)
4188       (subtarget, insn_data[icode].operand[0].mode))
4189     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4190
4191   if (! (*insn_data[icode].operand[2].predicate)
4192       (op2, insn_data[icode].operand[2].mode))
4193     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4194
4195   if (! (*insn_data[icode].operand[3].predicate)
4196       (op3, insn_data[icode].operand[3].mode))
4197     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4198
4199   /* Everything should now be in the suitable form, so emit the compare insn
4200      and then the conditional move.  */
4201
4202   comparison
4203     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4204
4205   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4206   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4207      return NULL and let the caller figure out how best to deal with this
4208      situation.  */
4209   if (GET_CODE (comparison) != code)
4210     return NULL_RTX;
4211
4212   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4213
4214   /* If that failed, then give up.  */
4215   if (insn == 0)
4216     return 0;
4217
4218   emit_insn (insn);
4219
4220   if (subtarget != target)
4221     convert_move (target, subtarget, 0);
4222
4223   return target;
4224 }
4225
4226 /* Return nonzero if a conditional move of mode MODE is supported.
4227
4228    This function is for combine so it can tell whether an insn that looks
4229    like a conditional move is actually supported by the hardware.  If we
4230    guess wrong we lose a bit on optimization, but that's it.  */
4231 /* ??? sparc64 supports conditionally moving integers values based on fp
4232    comparisons, and vice versa.  How do we handle them?  */
4233
4234 int
4235 can_conditionally_move_p (enum machine_mode mode)
4236 {
4237   if (movcc_gen_code[mode] != CODE_FOR_nothing)
4238     return 1;
4239
4240   return 0;
4241 }
4242
4243 #endif /* HAVE_conditional_move */
4244
4245 /* Emit a conditional addition instruction if the machine supports one for that
4246    condition and machine mode.
4247
4248    OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4249    the mode to use should they be constants.  If it is VOIDmode, they cannot
4250    both be constants.
4251
4252    OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4253    should be stored there.  MODE is the mode to use should they be constants.
4254    If it is VOIDmode, they cannot both be constants.
4255
4256    The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4257    is not supported.  */
4258
4259 rtx
4260 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4261                       enum machine_mode cmode, rtx op2, rtx op3,
4262                       enum machine_mode mode, int unsignedp)
4263 {
4264   rtx tem, subtarget, comparison, insn;
4265   enum insn_code icode;
4266   enum rtx_code reversed;
4267
4268   /* If one operand is constant, make it the second one.  Only do this
4269      if the other operand is not constant as well.  */
4270
4271   if (swap_commutative_operands_p (op0, op1))
4272     {
4273       tem = op0;
4274       op0 = op1;
4275       op1 = tem;
4276       code = swap_condition (code);
4277     }
4278
4279   /* get_condition will prefer to generate LT and GT even if the old
4280      comparison was against zero, so undo that canonicalization here since
4281      comparisons against zero are cheaper.  */
4282   if (code == LT && op1 == const1_rtx)
4283     code = LE, op1 = const0_rtx;
4284   else if (code == GT && op1 == constm1_rtx)
4285     code = GE, op1 = const0_rtx;
4286
4287   if (cmode == VOIDmode)
4288     cmode = GET_MODE (op0);
4289
4290   if (swap_commutative_operands_p (op2, op3)
4291       && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4292           != UNKNOWN))
4293     {
4294       tem = op2;
4295       op2 = op3;
4296       op3 = tem;
4297       code = reversed;
4298     }
4299
4300   if (mode == VOIDmode)
4301     mode = GET_MODE (op2);
4302
4303   icode = addcc_optab->handlers[(int) mode].insn_code;
4304
4305   if (icode == CODE_FOR_nothing)
4306     return 0;
4307
4308   if (flag_force_mem)
4309     {
4310       op2 = force_not_mem (op2);
4311       op3 = force_not_mem (op3);
4312     }
4313
4314   if (target)
4315     target = protect_from_queue (target, 1);
4316   else
4317     target = gen_reg_rtx (mode);
4318
4319   subtarget = target;
4320
4321   emit_queue ();
4322
4323   op2 = protect_from_queue (op2, 0);
4324   op3 = protect_from_queue (op3, 0);
4325
4326   /* If the insn doesn't accept these operands, put them in pseudos.  */
4327
4328   if (! (*insn_data[icode].operand[0].predicate)
4329       (subtarget, insn_data[icode].operand[0].mode))
4330     subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4331
4332   if (! (*insn_data[icode].operand[2].predicate)
4333       (op2, insn_data[icode].operand[2].mode))
4334     op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4335
4336   if (! (*insn_data[icode].operand[3].predicate)
4337       (op3, insn_data[icode].operand[3].mode))
4338     op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4339
4340   /* Everything should now be in the suitable form, so emit the compare insn
4341      and then the conditional move.  */
4342
4343   comparison
4344     = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4345
4346   /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)?  */
4347   /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4348      return NULL and let the caller figure out how best to deal with this
4349      situation.  */
4350   if (GET_CODE (comparison) != code)
4351     return NULL_RTX;
4352
4353   insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4354
4355   /* If that failed, then give up.  */
4356   if (insn == 0)
4357     return 0;
4358
4359   emit_insn (insn);
4360
4361   if (subtarget != target)
4362     convert_move (target, subtarget, 0);
4363
4364   return target;
4365 }
4366 \f
4367 /* These functions attempt to generate an insn body, rather than
4368    emitting the insn, but if the gen function already emits them, we
4369    make no attempt to turn them back into naked patterns.
4370
4371    They do not protect from queued increments,
4372    because they may be used 1) in protect_from_queue itself
4373    and 2) in other passes where there is no queue.  */
4374
4375 /* Generate and return an insn body to add Y to X.  */
4376
4377 rtx
4378 gen_add2_insn (rtx x, rtx y)
4379 {
4380   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4381
4382   if (! ((*insn_data[icode].operand[0].predicate)
4383          (x, insn_data[icode].operand[0].mode))
4384       || ! ((*insn_data[icode].operand[1].predicate)
4385             (x, insn_data[icode].operand[1].mode))
4386       || ! ((*insn_data[icode].operand[2].predicate)
4387             (y, insn_data[icode].operand[2].mode)))
4388     abort ();
4389
4390   return (GEN_FCN (icode) (x, x, y));
4391 }
4392
4393 /* Generate and return an insn body to add r1 and c,
4394    storing the result in r0.  */
4395 rtx
4396 gen_add3_insn (rtx r0, rtx r1, rtx c)
4397 {
4398   int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4399
4400   if (icode == CODE_FOR_nothing
4401       || ! ((*insn_data[icode].operand[0].predicate)
4402             (r0, insn_data[icode].operand[0].mode))
4403       || ! ((*insn_data[icode].operand[1].predicate)
4404             (r1, insn_data[icode].operand[1].mode))
4405       || ! ((*insn_data[icode].operand[2].predicate)
4406             (c, insn_data[icode].operand[2].mode)))
4407     return NULL_RTX;
4408
4409   return (GEN_FCN (icode) (r0, r1, c));
4410 }
4411
4412 int
4413 have_add2_insn (rtx x, rtx y)
4414 {
4415   int icode;
4416
4417   if (GET_MODE (x) == VOIDmode)
4418     abort ();
4419
4420   icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4421
4422   if (icode == CODE_FOR_nothing)
4423     return 0;
4424
4425   if (! ((*insn_data[icode].operand[0].predicate)
4426          (x, insn_data[icode].operand[0].mode))
4427       || ! ((*insn_data[icode].operand[1].predicate)
4428             (x, insn_data[icode].operand[1].mode))
4429       || ! ((*insn_data[icode].operand[2].predicate)
4430             (y, insn_data[icode].operand[2].mode)))
4431     return 0;
4432
4433   return 1;
4434 }
4435
4436 /* Generate and return an insn body to subtract Y from X.  */
4437
4438 rtx
4439 gen_sub2_insn (rtx x, rtx y)
4440 {
4441   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4442
4443   if (! ((*insn_data[icode].operand[0].predicate)
4444          (x, insn_data[icode].operand[0].mode))
4445       || ! ((*insn_data[icode].operand[1].predicate)
4446             (x, insn_data[icode].operand[1].mode))
4447       || ! ((*insn_data[icode].operand[2].predicate)
4448             (y, insn_data[icode].operand[2].mode)))
4449     abort ();
4450
4451   return (GEN_FCN (icode) (x, x, y));
4452 }
4453
4454 /* Generate and return an insn body to subtract r1 and c,
4455    storing the result in r0.  */
4456 rtx
4457 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4458 {
4459   int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4460
4461   if (icode == CODE_FOR_nothing
4462       || ! ((*insn_data[icode].operand[0].predicate)
4463             (r0, insn_data[icode].operand[0].mode))
4464       || ! ((*insn_data[icode].operand[1].predicate)
4465             (r1, insn_data[icode].operand[1].mode))
4466       || ! ((*insn_data[icode].operand[2].predicate)
4467             (c, insn_data[icode].operand[2].mode)))
4468     return NULL_RTX;
4469
4470   return (GEN_FCN (icode) (r0, r1, c));
4471 }
4472
4473 int
4474 have_sub2_insn (rtx x, rtx y)
4475 {
4476   int icode;
4477
4478   if (GET_MODE (x) == VOIDmode)
4479     abort ();
4480
4481   icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4482
4483   if (icode == CODE_FOR_nothing)
4484     return 0;
4485
4486   if (! ((*insn_data[icode].operand[0].predicate)
4487          (x, insn_data[icode].operand[0].mode))
4488       || ! ((*insn_data[icode].operand[1].predicate)
4489             (x, insn_data[icode].operand[1].mode))
4490       || ! ((*insn_data[icode].operand[2].predicate)
4491             (y, insn_data[icode].operand[2].mode)))
4492     return 0;
4493
4494   return 1;
4495 }
4496
4497 /* Generate the body of an instruction to copy Y into X.
4498    It may be a list of insns, if one insn isn't enough.  */
4499
4500 rtx
4501 gen_move_insn (rtx x, rtx y)
4502 {
4503   rtx seq;
4504
4505   start_sequence ();
4506   emit_move_insn_1 (x, y);
4507   seq = get_insns ();
4508   end_sequence ();
4509   return seq;
4510 }
4511 \f
4512 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4513    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4514    no such operation exists, CODE_FOR_nothing will be returned.  */
4515
4516 enum insn_code
4517 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4518               int unsignedp)
4519 {
4520   convert_optab tab;
4521 #ifdef HAVE_ptr_extend
4522   if (unsignedp < 0)
4523     return CODE_FOR_ptr_extend;
4524 #endif
4525
4526   tab = unsignedp ? zext_optab : sext_optab;
4527   return tab->handlers[to_mode][from_mode].insn_code;
4528 }
4529
4530 /* Generate the body of an insn to extend Y (with mode MFROM)
4531    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4532
4533 rtx
4534 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4535                  enum machine_mode mfrom, int unsignedp)
4536 {
4537   enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4538   return GEN_FCN (icode) (x, y);
4539 }
4540 \f
4541 /* can_fix_p and can_float_p say whether the target machine
4542    can directly convert a given fixed point type to
4543    a given floating point type, or vice versa.
4544    The returned value is the CODE_FOR_... value to use,
4545    or CODE_FOR_nothing if these modes cannot be directly converted.
4546
4547    *TRUNCP_PTR is set to 1 if it is necessary to output
4548    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4549
4550 static enum insn_code
4551 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4552            int unsignedp, int *truncp_ptr)
4553 {
4554   convert_optab tab;
4555   enum insn_code icode;
4556
4557   tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4558   icode = tab->handlers[fixmode][fltmode].insn_code;
4559   if (icode != CODE_FOR_nothing)
4560     {
4561       *truncp_ptr = 0;
4562       return icode;
4563     }
4564
4565   /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4566      for this to work. We need to rework the fix* and ftrunc* patterns
4567      and documentation.  */
4568   tab = unsignedp ? ufix_optab : sfix_optab;
4569   icode = tab->handlers[fixmode][fltmode].insn_code;
4570   if (icode != CODE_FOR_nothing
4571       && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4572     {
4573       *truncp_ptr = 1;
4574       return icode;
4575     }
4576
4577   *truncp_ptr = 0;
4578   return CODE_FOR_nothing;
4579 }
4580
4581 static enum insn_code
4582 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4583              int unsignedp)
4584 {
4585   convert_optab tab;
4586
4587   tab = unsignedp ? ufloat_optab : sfloat_optab;
4588   return tab->handlers[fltmode][fixmode].insn_code;
4589 }
4590 \f
4591 /* Generate code to convert FROM to floating point
4592    and store in TO.  FROM must be fixed point and not VOIDmode.
4593    UNSIGNEDP nonzero means regard FROM as unsigned.
4594    Normally this is done by correcting the final value
4595    if it is negative.  */
4596
4597 void
4598 expand_float (rtx to, rtx from, int unsignedp)
4599 {
4600   enum insn_code icode;
4601   rtx target = to;
4602   enum machine_mode fmode, imode;
4603
4604   /* Crash now, because we won't be able to decide which mode to use.  */
4605   if (GET_MODE (from) == VOIDmode)
4606     abort ();
4607
4608   /* Look for an insn to do the conversion.  Do it in the specified
4609      modes if possible; otherwise convert either input, output or both to
4610      wider mode.  If the integer mode is wider than the mode of FROM,
4611      we can do the conversion signed even if the input is unsigned.  */
4612
4613   for (fmode = GET_MODE (to); fmode != VOIDmode;
4614        fmode = GET_MODE_WIDER_MODE (fmode))
4615     for (imode = GET_MODE (from); imode != VOIDmode;
4616          imode = GET_MODE_WIDER_MODE (imode))
4617       {
4618         int doing_unsigned = unsignedp;
4619
4620         if (fmode != GET_MODE (to)
4621             && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4622           continue;
4623
4624         icode = can_float_p (fmode, imode, unsignedp);
4625         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4626           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4627
4628         if (icode != CODE_FOR_nothing)
4629           {
4630             to = protect_from_queue (to, 1);
4631             from = protect_from_queue (from, 0);
4632
4633             if (imode != GET_MODE (from))
4634               from = convert_to_mode (imode, from, unsignedp);
4635
4636             if (fmode != GET_MODE (to))
4637               target = gen_reg_rtx (fmode);
4638
4639             emit_unop_insn (icode, target, from,
4640                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4641
4642             if (target != to)
4643               convert_move (to, target, 0);
4644             return;
4645           }
4646       }
4647
4648   /* Unsigned integer, and no way to convert directly.
4649      Convert as signed, then conditionally adjust the result.  */
4650   if (unsignedp)
4651     {
4652       rtx label = gen_label_rtx ();
4653       rtx temp;
4654       REAL_VALUE_TYPE offset;
4655
4656       emit_queue ();
4657
4658       to = protect_from_queue (to, 1);
4659       from = protect_from_queue (from, 0);
4660
4661       if (flag_force_mem)
4662         from = force_not_mem (from);
4663
4664       /* Look for a usable floating mode FMODE wider than the source and at
4665          least as wide as the target.  Using FMODE will avoid rounding woes
4666          with unsigned values greater than the signed maximum value.  */
4667
4668       for (fmode = GET_MODE (to);  fmode != VOIDmode;
4669            fmode = GET_MODE_WIDER_MODE (fmode))
4670         if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4671             && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4672           break;
4673
4674       if (fmode == VOIDmode)
4675         {
4676           /* There is no such mode.  Pretend the target is wide enough.  */
4677           fmode = GET_MODE (to);
4678
4679           /* Avoid double-rounding when TO is narrower than FROM.  */
4680           if ((significand_size (fmode) + 1)
4681               < GET_MODE_BITSIZE (GET_MODE (from)))
4682             {
4683               rtx temp1;
4684               rtx neglabel = gen_label_rtx ();
4685
4686               /* Don't use TARGET if it isn't a register, is a hard register,
4687                  or is the wrong mode.  */
4688               if (GET_CODE (target) != REG
4689                   || REGNO (target) < FIRST_PSEUDO_REGISTER
4690                   || GET_MODE (target) != fmode)
4691                 target = gen_reg_rtx (fmode);
4692
4693               imode = GET_MODE (from);
4694               do_pending_stack_adjust ();
4695
4696               /* Test whether the sign bit is set.  */
4697               emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4698                                        0, neglabel);
4699
4700               /* The sign bit is not set.  Convert as signed.  */
4701               expand_float (target, from, 0);
4702               emit_jump_insn (gen_jump (label));
4703               emit_barrier ();
4704
4705               /* The sign bit is set.
4706                  Convert to a usable (positive signed) value by shifting right
4707                  one bit, while remembering if a nonzero bit was shifted
4708                  out; i.e., compute  (from & 1) | (from >> 1).  */
4709
4710               emit_label (neglabel);
4711               temp = expand_binop (imode, and_optab, from, const1_rtx,
4712                                    NULL_RTX, 1, OPTAB_LIB_WIDEN);
4713               temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4714                                     NULL_RTX, 1);
4715               temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4716                                    OPTAB_LIB_WIDEN);
4717               expand_float (target, temp, 0);
4718
4719               /* Multiply by 2 to undo the shift above.  */
4720               temp = expand_binop (fmode, add_optab, target, target,
4721                                    target, 0, OPTAB_LIB_WIDEN);
4722               if (temp != target)
4723                 emit_move_insn (target, temp);
4724
4725               do_pending_stack_adjust ();
4726               emit_label (label);
4727               goto done;
4728             }
4729         }
4730
4731       /* If we are about to do some arithmetic to correct for an
4732          unsigned operand, do it in a pseudo-register.  */
4733
4734       if (GET_MODE (to) != fmode
4735           || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4736         target = gen_reg_rtx (fmode);
4737
4738       /* Convert as signed integer to floating.  */
4739       expand_float (target, from, 0);
4740
4741       /* If FROM is negative (and therefore TO is negative),
4742          correct its value by 2**bitwidth.  */
4743
4744       do_pending_stack_adjust ();
4745       emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4746                                0, label);
4747
4748
4749       real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4750       temp = expand_binop (fmode, add_optab, target,
4751                            CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4752                            target, 0, OPTAB_LIB_WIDEN);
4753       if (temp != target)
4754         emit_move_insn (target, temp);
4755
4756       do_pending_stack_adjust ();
4757       emit_label (label);
4758       goto done;
4759     }
4760
4761   /* No hardware instruction available; call a library routine.  */
4762     {
4763       rtx libfunc;
4764       rtx insns;
4765       rtx value;
4766       convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4767
4768       to = protect_from_queue (to, 1);
4769       from = protect_from_queue (from, 0);
4770
4771       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4772         from = convert_to_mode (SImode, from, unsignedp);
4773
4774       if (flag_force_mem)
4775         from = force_not_mem (from);
4776
4777       libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4778       if (!libfunc)
4779         abort ();
4780
4781       start_sequence ();
4782
4783       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4784                                        GET_MODE (to), 1, from,
4785                                        GET_MODE (from));
4786       insns = get_insns ();
4787       end_sequence ();
4788
4789       emit_libcall_block (insns, target, value,
4790                           gen_rtx_FLOAT (GET_MODE (to), from));
4791     }
4792
4793  done:
4794
4795   /* Copy result to requested destination
4796      if we have been computing in a temp location.  */
4797
4798   if (target != to)
4799     {
4800       if (GET_MODE (target) == GET_MODE (to))
4801         emit_move_insn (to, target);
4802       else
4803         convert_move (to, target, 0);
4804     }
4805 }
4806 \f
4807 /* Generate code to convert FROM to fixed point and store in TO.  FROM
4808    must be floating point.  */
4809
4810 void
4811 expand_fix (rtx to, rtx from, int unsignedp)
4812 {
4813   enum insn_code icode;
4814   rtx target = to;
4815   enum machine_mode fmode, imode;
4816   int must_trunc = 0;
4817
4818   /* We first try to find a pair of modes, one real and one integer, at
4819      least as wide as FROM and TO, respectively, in which we can open-code
4820      this conversion.  If the integer mode is wider than the mode of TO,
4821      we can do the conversion either signed or unsigned.  */
4822
4823   for (fmode = GET_MODE (from); fmode != VOIDmode;
4824        fmode = GET_MODE_WIDER_MODE (fmode))
4825     for (imode = GET_MODE (to); imode != VOIDmode;
4826          imode = GET_MODE_WIDER_MODE (imode))
4827       {
4828         int doing_unsigned = unsignedp;
4829
4830         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4831         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4832           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4833
4834         if (icode != CODE_FOR_nothing)
4835           {
4836             to = protect_from_queue (to, 1);
4837             from = protect_from_queue (from, 0);
4838
4839             if (fmode != GET_MODE (from))
4840               from = convert_to_mode (fmode, from, 0);
4841
4842             if (must_trunc)
4843               {
4844                 rtx temp = gen_reg_rtx (GET_MODE (from));
4845                 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4846                                     temp, 0);
4847               }
4848
4849             if (imode != GET_MODE (to))
4850               target = gen_reg_rtx (imode);
4851
4852             emit_unop_insn (icode, target, from,
4853                             doing_unsigned ? UNSIGNED_FIX : FIX);
4854             if (target != to)
4855               convert_move (to, target, unsignedp);
4856             return;
4857           }
4858       }
4859
4860   /* For an unsigned conversion, there is one more way to do it.
4861      If we have a signed conversion, we generate code that compares
4862      the real value to the largest representable positive number.  If if
4863      is smaller, the conversion is done normally.  Otherwise, subtract
4864      one plus the highest signed number, convert, and add it back.
4865
4866      We only need to check all real modes, since we know we didn't find
4867      anything with a wider integer mode.
4868
4869      This code used to extend FP value into mode wider than the destination.
4870      This is not needed.  Consider, for instance conversion from SFmode
4871      into DImode.
4872
4873      The hot path trought the code is dealing with inputs smaller than 2^63
4874      and doing just the conversion, so there is no bits to lose.
4875
4876      In the other path we know the value is positive in the range 2^63..2^64-1
4877      inclusive.  (as for other imput overflow happens and result is undefined)
4878      So we know that the most important bit set in mantissa corresponds to
4879      2^63.  The subtraction of 2^63 should not generate any rounding as it
4880      simply clears out that bit.  The rest is trivial.  */
4881
4882   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4883     for (fmode = GET_MODE (from); fmode != VOIDmode;
4884          fmode = GET_MODE_WIDER_MODE (fmode))
4885       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4886                                          &must_trunc))
4887         {
4888           int bitsize;
4889           REAL_VALUE_TYPE offset;
4890           rtx limit, lab1, lab2, insn;
4891
4892           bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4893           real_2expN (&offset, bitsize - 1);
4894           limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4895           lab1 = gen_label_rtx ();
4896           lab2 = gen_label_rtx ();
4897
4898           emit_queue ();
4899           to = protect_from_queue (to, 1);
4900           from = protect_from_queue (from, 0);
4901
4902           if (flag_force_mem)
4903             from = force_not_mem (from);
4904
4905           if (fmode != GET_MODE (from))
4906             from = convert_to_mode (fmode, from, 0);
4907
4908           /* See if we need to do the subtraction.  */
4909           do_pending_stack_adjust ();
4910           emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4911                                    0, lab1);
4912
4913           /* If not, do the signed "fix" and branch around fixup code.  */
4914           expand_fix (to, from, 0);
4915           emit_jump_insn (gen_jump (lab2));
4916           emit_barrier ();
4917
4918           /* Otherwise, subtract 2**(N-1), convert to signed number,
4919              then add 2**(N-1).  Do the addition using XOR since this
4920              will often generate better code.  */
4921           emit_label (lab1);
4922           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4923                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
4924           expand_fix (to, target, 0);
4925           target = expand_binop (GET_MODE (to), xor_optab, to,
4926                                  gen_int_mode
4927                                  ((HOST_WIDE_INT) 1 << (bitsize - 1),
4928                                   GET_MODE (to)),
4929                                  to, 1, OPTAB_LIB_WIDEN);
4930
4931           if (target != to)
4932             emit_move_insn (to, target);
4933
4934           emit_label (lab2);
4935
4936           if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4937               != CODE_FOR_nothing)
4938             {
4939               /* Make a place for a REG_NOTE and add it.  */
4940               insn = emit_move_insn (to, to);
4941               set_unique_reg_note (insn,
4942                                    REG_EQUAL,
4943                                    gen_rtx_fmt_e (UNSIGNED_FIX,
4944                                                   GET_MODE (to),
4945                                                   copy_rtx (from)));
4946             }
4947
4948           return;
4949         }
4950
4951   /* We can't do it with an insn, so use a library call.  But first ensure
4952      that the mode of TO is at least as wide as SImode, since those are the
4953      only library calls we know about.  */
4954
4955   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4956     {
4957       target = gen_reg_rtx (SImode);
4958
4959       expand_fix (target, from, unsignedp);
4960     }
4961   else
4962     {
4963       rtx insns;
4964       rtx value;
4965       rtx libfunc;
4966       
4967       convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4968       libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4969       if (!libfunc)
4970         abort ();
4971
4972       to = protect_from_queue (to, 1);
4973       from = protect_from_queue (from, 0);
4974
4975       if (flag_force_mem)
4976         from = force_not_mem (from);
4977
4978       start_sequence ();
4979
4980       value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4981                                        GET_MODE (to), 1, from,
4982                                        GET_MODE (from));
4983       insns = get_insns ();
4984       end_sequence ();
4985
4986       emit_libcall_block (insns, target, value,
4987                           gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4988                                          GET_MODE (to), from));
4989     }
4990
4991   if (target != to)
4992     {
4993       if (GET_MODE (to) == GET_MODE (target))
4994         emit_move_insn (to, target);
4995       else
4996         convert_move (to, target, 0);
4997     }
4998 }
4999 \f
5000 /* Report whether we have an instruction to perform the operation
5001    specified by CODE on operands of mode MODE.  */
5002 int
5003 have_insn_for (enum rtx_code code, enum machine_mode mode)
5004 {
5005   return (code_to_optab[(int) code] != 0
5006           && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
5007               != CODE_FOR_nothing));
5008 }
5009
5010 /* Create a blank optab.  */
5011 static optab
5012 new_optab (void)
5013 {
5014   int i;
5015   optab op = ggc_alloc (sizeof (struct optab));
5016   for (i = 0; i < NUM_MACHINE_MODES; i++)
5017     {
5018       op->handlers[i].insn_code = CODE_FOR_nothing;
5019       op->handlers[i].libfunc = 0;
5020     }
5021
5022   return op;
5023 }
5024
5025 static convert_optab
5026 new_convert_optab (void)
5027 {
5028   int i, j;
5029   convert_optab op = ggc_alloc (sizeof (struct convert_optab));
5030   for (i = 0; i < NUM_MACHINE_MODES; i++)
5031     for (j = 0; j < NUM_MACHINE_MODES; j++)
5032       {
5033         op->handlers[i][j].insn_code = CODE_FOR_nothing;
5034         op->handlers[i][j].libfunc = 0;
5035       }
5036   return op;
5037 }
5038
5039 /* Same, but fill in its code as CODE, and write it into the
5040    code_to_optab table.  */
5041 static inline optab
5042 init_optab (enum rtx_code code)
5043 {
5044   optab op = new_optab ();
5045   op->code = code;
5046   code_to_optab[(int) code] = op;
5047   return op;
5048 }
5049
5050 /* Same, but fill in its code as CODE, and do _not_ write it into
5051    the code_to_optab table.  */
5052 static inline optab
5053 init_optabv (enum rtx_code code)
5054 {
5055   optab op = new_optab ();
5056   op->code = code;
5057   return op;
5058 }
5059
5060 /* Conversion optabs never go in the code_to_optab table.  */
5061 static inline convert_optab
5062 init_convert_optab (enum rtx_code code)
5063 {
5064   convert_optab op = new_convert_optab ();
5065   op->code = code;
5066   return op;
5067 }
5068
5069 /* Initialize the libfunc fields of an entire group of entries in some
5070    optab.  Each entry is set equal to a string consisting of a leading
5071    pair of underscores followed by a generic operation name followed by
5072    a mode name (downshifted to lowercase) followed by a single character
5073    representing the number of operands for the given operation (which is
5074    usually one of the characters '2', '3', or '4').
5075
5076    OPTABLE is the table in which libfunc fields are to be initialized.
5077    FIRST_MODE is the first machine mode index in the given optab to
5078      initialize.
5079    LAST_MODE is the last machine mode index in the given optab to
5080      initialize.
5081    OPNAME is the generic (string) name of the operation.
5082    SUFFIX is the character which specifies the number of operands for
5083      the given generic operation.
5084 */
5085
5086 static void
5087 init_libfuncs (optab optable, int first_mode, int last_mode,
5088                const char *opname, int suffix)
5089 {
5090   int mode;
5091   unsigned opname_len = strlen (opname);
5092
5093   for (mode = first_mode; (int) mode <= (int) last_mode;
5094        mode = (enum machine_mode) ((int) mode + 1))
5095     {
5096       const char *mname = GET_MODE_NAME (mode);
5097       unsigned mname_len = strlen (mname);
5098       char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5099       char *p;
5100       const char *q;
5101
5102       p = libfunc_name;
5103       *p++ = '_';
5104       *p++ = '_';
5105       for (q = opname; *q; )
5106         *p++ = *q++;
5107       for (q = mname; *q; q++)
5108         *p++ = TOLOWER (*q);
5109       *p++ = suffix;
5110       *p = '\0';
5111
5112       optable->handlers[(int) mode].libfunc
5113         = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5114     }
5115 }
5116
5117 /* Initialize the libfunc fields of an entire group of entries in some
5118    optab which correspond to all integer mode operations.  The parameters
5119    have the same meaning as similarly named ones for the `init_libfuncs'
5120    routine.  (See above).  */
5121
5122 static void
5123 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5124 {
5125   int maxsize = 2*BITS_PER_WORD;
5126   if (maxsize < LONG_LONG_TYPE_SIZE)
5127     maxsize = LONG_LONG_TYPE_SIZE;
5128   init_libfuncs (optable, word_mode,
5129                  mode_for_size (maxsize, MODE_INT, 0),
5130                  opname, suffix);
5131 }
5132
5133 /* Initialize the libfunc fields of an entire group of entries in some
5134    optab which correspond to all real mode operations.  The parameters
5135    have the same meaning as similarly named ones for the `init_libfuncs'
5136    routine.  (See above).  */
5137
5138 static void
5139 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5140 {
5141   init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5142 }
5143
5144 /* Initialize the libfunc fields of an entire group of entries of an
5145    inter-mode-class conversion optab.  The string formation rules are
5146    similar to the ones for init_libfuncs, above, but instead of having
5147    a mode name and an operand count these functions have two mode names
5148    and no operand count.  */
5149 static void
5150 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5151                                enum mode_class from_class,
5152                                enum mode_class to_class)
5153 {
5154   enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5155   enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5156   size_t opname_len = strlen (opname);
5157   size_t max_mname_len = 0;
5158
5159   enum machine_mode fmode, tmode;
5160   const char *fname, *tname;
5161   const char *q;
5162   char *libfunc_name, *suffix;
5163   char *p;
5164
5165   for (fmode = first_from_mode;
5166        fmode != VOIDmode;
5167        fmode = GET_MODE_WIDER_MODE (fmode))
5168     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5169
5170   for (tmode = first_to_mode;
5171        tmode != VOIDmode;
5172        tmode = GET_MODE_WIDER_MODE (tmode))
5173     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5174
5175   libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5176   libfunc_name[0] = '_';
5177   libfunc_name[1] = '_';
5178   memcpy (&libfunc_name[2], opname, opname_len);
5179   suffix = libfunc_name + opname_len + 2;
5180
5181   for (fmode = first_from_mode; fmode != VOIDmode;
5182        fmode = GET_MODE_WIDER_MODE (fmode))
5183     for (tmode = first_to_mode; tmode != VOIDmode;
5184          tmode = GET_MODE_WIDER_MODE (tmode))
5185       {
5186         fname = GET_MODE_NAME (fmode);
5187         tname = GET_MODE_NAME (tmode);
5188
5189         p = suffix;
5190         for (q = fname; *q; p++, q++)
5191           *p = TOLOWER (*q);
5192         for (q = tname; *q; p++, q++)
5193           *p = TOLOWER (*q);
5194
5195         *p = '\0';
5196
5197         tab->handlers[tmode][fmode].libfunc
5198           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5199                                                 p - libfunc_name));
5200       }
5201 }
5202
5203 /* Initialize the libfunc fields of an entire group of entries of an
5204    intra-mode-class conversion optab.  The string formation rules are
5205    similar to the ones for init_libfunc, above.  WIDENING says whether
5206    the optab goes from narrow to wide modes or vice versa.  These functions
5207    have two mode names _and_ an operand count.  */
5208 static void
5209 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5210                                enum mode_class class, bool widening)
5211 {
5212   enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5213   size_t opname_len = strlen (opname);
5214   size_t max_mname_len = 0;
5215
5216   enum machine_mode nmode, wmode;
5217   const char *nname, *wname;
5218   const char *q;
5219   char *libfunc_name, *suffix;
5220   char *p;
5221
5222   for (nmode = first_mode; nmode != VOIDmode;
5223        nmode = GET_MODE_WIDER_MODE (nmode))
5224     max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5225
5226   libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5227   libfunc_name[0] = '_';
5228   libfunc_name[1] = '_';
5229   memcpy (&libfunc_name[2], opname, opname_len);
5230   suffix = libfunc_name + opname_len + 2;
5231
5232   for (nmode = first_mode; nmode != VOIDmode;
5233        nmode = GET_MODE_WIDER_MODE (nmode))
5234     for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5235          wmode = GET_MODE_WIDER_MODE (wmode))
5236       {
5237         nname = GET_MODE_NAME (nmode);
5238         wname = GET_MODE_NAME (wmode);
5239
5240         p = suffix;
5241         for (q = widening ? nname : wname; *q; p++, q++)
5242           *p = TOLOWER (*q);
5243         for (q = widening ? wname : nname; *q; p++, q++)
5244           *p = TOLOWER (*q);
5245
5246         *p++ = '2';
5247         *p = '\0';
5248
5249         tab->handlers[widening ? wmode : nmode]
5250                      [widening ? nmode : wmode].libfunc
5251           = init_one_libfunc (ggc_alloc_string (libfunc_name,
5252                                                 p - libfunc_name));
5253       }
5254 }
5255
5256
5257 rtx
5258 init_one_libfunc (const char *name)
5259 {
5260   rtx symbol;
5261
5262   /* Create a FUNCTION_DECL that can be passed to
5263      targetm.encode_section_info.  */
5264   /* ??? We don't have any type information except for this is
5265      a function.  Pretend this is "int foo()".  */
5266   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5267                           build_function_type (integer_type_node, NULL_TREE));
5268   DECL_ARTIFICIAL (decl) = 1;
5269   DECL_EXTERNAL (decl) = 1;
5270   TREE_PUBLIC (decl) = 1;
5271
5272   symbol = XEXP (DECL_RTL (decl), 0);
5273
5274   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
5275      are the flags assigned by targetm.encode_section_info.  */
5276   SYMBOL_REF_DECL (symbol) = 0;
5277
5278   return symbol;
5279 }
5280
5281 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5282    MODE to NAME, which should be either 0 or a string constant.  */
5283 void
5284 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5285 {
5286   if (name)
5287     optable->handlers[mode].libfunc = init_one_libfunc (name);
5288   else
5289     optable->handlers[mode].libfunc = 0;
5290 }
5291
5292 /* Call this to reset the function entry for one conversion optab
5293    (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5294    either 0 or a string constant.  */
5295 void
5296 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5297                   enum machine_mode fmode, const char *name)
5298 {
5299   if (name)
5300     optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5301   else
5302     optable->handlers[tmode][fmode].libfunc = 0;
5303 }
5304
5305 /* Call this once to initialize the contents of the optabs
5306    appropriately for the current target machine.  */
5307
5308 void
5309 init_optabs (void)
5310 {
5311   unsigned int i;
5312
5313   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
5314
5315   for (i = 0; i < NUM_RTX_CODE; i++)
5316     setcc_gen_code[i] = CODE_FOR_nothing;
5317
5318 #ifdef HAVE_conditional_move
5319   for (i = 0; i < NUM_MACHINE_MODES; i++)
5320     movcc_gen_code[i] = CODE_FOR_nothing;
5321 #endif
5322
5323   add_optab = init_optab (PLUS);
5324   addv_optab = init_optabv (PLUS);
5325   sub_optab = init_optab (MINUS);
5326   subv_optab = init_optabv (MINUS);
5327   smul_optab = init_optab (MULT);
5328   smulv_optab = init_optabv (MULT);
5329   smul_highpart_optab = init_optab (UNKNOWN);
5330   umul_highpart_optab = init_optab (UNKNOWN);
5331   smul_widen_optab = init_optab (UNKNOWN);
5332   umul_widen_optab = init_optab (UNKNOWN);
5333   sdiv_optab = init_optab (DIV);
5334   sdivv_optab = init_optabv (DIV);
5335   sdivmod_optab = init_optab (UNKNOWN);
5336   udiv_optab = init_optab (UDIV);
5337   udivmod_optab = init_optab (UNKNOWN);
5338   smod_optab = init_optab (MOD);
5339   umod_optab = init_optab (UMOD);
5340   fmod_optab = init_optab (UNKNOWN);
5341   drem_optab = init_optab (UNKNOWN);
5342   ftrunc_optab = init_optab (UNKNOWN);
5343   and_optab = init_optab (AND);
5344   ior_optab = init_optab (IOR);
5345   xor_optab = init_optab (XOR);
5346   ashl_optab = init_optab (ASHIFT);
5347   ashr_optab = init_optab (ASHIFTRT);
5348   lshr_optab = init_optab (LSHIFTRT);
5349   rotl_optab = init_optab (ROTATE);
5350   rotr_optab = init_optab (ROTATERT);
5351   smin_optab = init_optab (SMIN);
5352   smax_optab = init_optab (SMAX);
5353   umin_optab = init_optab (UMIN);
5354   umax_optab = init_optab (UMAX);
5355   pow_optab = init_optab (UNKNOWN);
5356   atan2_optab = init_optab (UNKNOWN);
5357
5358   /* These three have codes assigned exclusively for the sake of
5359      have_insn_for.  */
5360   mov_optab = init_optab (SET);
5361   movstrict_optab = init_optab (STRICT_LOW_PART);
5362   cmp_optab = init_optab (COMPARE);
5363
5364   ucmp_optab = init_optab (UNKNOWN);
5365   tst_optab = init_optab (UNKNOWN);
5366
5367   eq_optab = init_optab (EQ);
5368   ne_optab = init_optab (NE);
5369   gt_optab = init_optab (GT);
5370   ge_optab = init_optab (GE);
5371   lt_optab = init_optab (LT);
5372   le_optab = init_optab (LE);
5373   unord_optab = init_optab (UNORDERED);
5374
5375   neg_optab = init_optab (NEG);
5376   negv_optab = init_optabv (NEG);
5377   abs_optab = init_optab (ABS);
5378   absv_optab = init_optabv (ABS);
5379   addcc_optab = init_optab (UNKNOWN);
5380   one_cmpl_optab = init_optab (NOT);
5381   ffs_optab = init_optab (FFS);
5382   clz_optab = init_optab (CLZ);
5383   ctz_optab = init_optab (CTZ);
5384   popcount_optab = init_optab (POPCOUNT);
5385   parity_optab = init_optab (PARITY);
5386   sqrt_optab = init_optab (SQRT);
5387   floor_optab = init_optab (UNKNOWN);
5388   ceil_optab = init_optab (UNKNOWN);
5389   round_optab = init_optab (UNKNOWN);
5390   btrunc_optab = init_optab (UNKNOWN);
5391   nearbyint_optab = init_optab (UNKNOWN);
5392   sincos_optab = init_optab (UNKNOWN);
5393   sin_optab = init_optab (UNKNOWN);
5394   asin_optab = init_optab (UNKNOWN);
5395   cos_optab = init_optab (UNKNOWN);
5396   acos_optab = init_optab (UNKNOWN);
5397   exp_optab = init_optab (UNKNOWN);
5398   exp10_optab = init_optab (UNKNOWN);
5399   exp2_optab = init_optab (UNKNOWN);
5400   expm1_optab = init_optab (UNKNOWN);
5401   logb_optab = init_optab (UNKNOWN);
5402   ilogb_optab = init_optab (UNKNOWN);
5403   log_optab = init_optab (UNKNOWN);
5404   log10_optab = init_optab (UNKNOWN);
5405   log2_optab = init_optab (UNKNOWN);
5406   log1p_optab = init_optab (UNKNOWN);
5407   tan_optab = init_optab (UNKNOWN);
5408   atan_optab = init_optab (UNKNOWN);
5409   strlen_optab = init_optab (UNKNOWN);
5410   cbranch_optab = init_optab (UNKNOWN);
5411   cmov_optab = init_optab (UNKNOWN);
5412   cstore_optab = init_optab (UNKNOWN);
5413   push_optab = init_optab (UNKNOWN);
5414
5415   vec_extract_optab = init_optab (UNKNOWN);
5416   vec_set_optab = init_optab (UNKNOWN);
5417   vec_init_optab = init_optab (UNKNOWN);
5418   /* Conversions.  */
5419   sext_optab = init_convert_optab (SIGN_EXTEND);
5420   zext_optab = init_convert_optab (ZERO_EXTEND);
5421   trunc_optab = init_convert_optab (TRUNCATE);
5422   sfix_optab = init_convert_optab (FIX);
5423   ufix_optab = init_convert_optab (UNSIGNED_FIX);
5424   sfixtrunc_optab = init_convert_optab (UNKNOWN);
5425   ufixtrunc_optab = init_convert_optab (UNKNOWN);
5426   sfloat_optab = init_convert_optab (FLOAT);
5427   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5428
5429   for (i = 0; i < NUM_MACHINE_MODES; i++)
5430     {
5431       movstr_optab[i] = CODE_FOR_nothing;
5432       clrstr_optab[i] = CODE_FOR_nothing;
5433       cmpstr_optab[i] = CODE_FOR_nothing;
5434       cmpmem_optab[i] = CODE_FOR_nothing;
5435
5436 #ifdef HAVE_SECONDARY_RELOADS
5437       reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5438 #endif
5439     }
5440
5441   /* Fill in the optabs with the insns we support.  */
5442   init_all_optabs ();
5443
5444   /* Initialize the optabs with the names of the library functions.  */
5445   init_integral_libfuncs (add_optab, "add", '3');
5446   init_floating_libfuncs (add_optab, "add", '3');
5447   init_integral_libfuncs (addv_optab, "addv", '3');
5448   init_floating_libfuncs (addv_optab, "add", '3');
5449   init_integral_libfuncs (sub_optab, "sub", '3');
5450   init_floating_libfuncs (sub_optab, "sub", '3');
5451   init_integral_libfuncs (subv_optab, "subv", '3');
5452   init_floating_libfuncs (subv_optab, "sub", '3');
5453   init_integral_libfuncs (smul_optab, "mul", '3');
5454   init_floating_libfuncs (smul_optab, "mul", '3');
5455   init_integral_libfuncs (smulv_optab, "mulv", '3');
5456   init_floating_libfuncs (smulv_optab, "mul", '3');
5457   init_integral_libfuncs (sdiv_optab, "div", '3');
5458   init_floating_libfuncs (sdiv_optab, "div", '3');
5459   init_integral_libfuncs (sdivv_optab, "divv", '3');
5460   init_integral_libfuncs (udiv_optab, "udiv", '3');
5461   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5462   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5463   init_integral_libfuncs (smod_optab, "mod", '3');
5464   init_integral_libfuncs (umod_optab, "umod", '3');
5465   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5466   init_integral_libfuncs (and_optab, "and", '3');
5467   init_integral_libfuncs (ior_optab, "ior", '3');
5468   init_integral_libfuncs (xor_optab, "xor", '3');
5469   init_integral_libfuncs (ashl_optab, "ashl", '3');
5470   init_integral_libfuncs (ashr_optab, "ashr", '3');
5471   init_integral_libfuncs (lshr_optab, "lshr", '3');
5472   init_integral_libfuncs (smin_optab, "min", '3');
5473   init_floating_libfuncs (smin_optab, "min", '3');
5474   init_integral_libfuncs (smax_optab, "max", '3');
5475   init_floating_libfuncs (smax_optab, "max", '3');
5476   init_integral_libfuncs (umin_optab, "umin", '3');
5477   init_integral_libfuncs (umax_optab, "umax", '3');
5478   init_integral_libfuncs (neg_optab, "neg", '2');
5479   init_floating_libfuncs (neg_optab, "neg", '2');
5480   init_integral_libfuncs (negv_optab, "negv", '2');
5481   init_floating_libfuncs (negv_optab, "neg", '2');
5482   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5483   init_integral_libfuncs (ffs_optab, "ffs", '2');
5484   init_integral_libfuncs (clz_optab, "clz", '2');
5485   init_integral_libfuncs (ctz_optab, "ctz", '2');
5486   init_integral_libfuncs (popcount_optab, "popcount", '2');
5487   init_integral_libfuncs (parity_optab, "parity", '2');
5488
5489   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
5490   init_integral_libfuncs (cmp_optab, "cmp", '2');
5491   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5492   init_floating_libfuncs (cmp_optab, "cmp", '2');
5493
5494   /* EQ etc are floating point only.  */
5495   init_floating_libfuncs (eq_optab, "eq", '2');
5496   init_floating_libfuncs (ne_optab, "ne", '2');
5497   init_floating_libfuncs (gt_optab, "gt", '2');
5498   init_floating_libfuncs (ge_optab, "ge", '2');
5499   init_floating_libfuncs (lt_optab, "lt", '2');
5500   init_floating_libfuncs (le_optab, "le", '2');
5501   init_floating_libfuncs (unord_optab, "unord", '2');
5502
5503   /* Conversions.  */
5504   init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT);
5505   init_interclass_conv_libfuncs (sfix_optab, "fix",     MODE_FLOAT, MODE_INT);
5506   init_interclass_conv_libfuncs (ufix_optab, "fixuns",  MODE_FLOAT, MODE_INT);
5507
5508   /* sext_optab is also used for FLOAT_EXTEND.  */
5509   init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5510   init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5511
5512   /* Use cabs for double complex abs, since systems generally have cabs.
5513      Don't define any libcall for float complex, so that cabs will be used.  */
5514   if (complex_double_type_node)
5515     abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5516       = init_one_libfunc ("cabs");
5517
5518   /* The ffs function operates on `int'.  */
5519   ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5520     = init_one_libfunc ("ffs");
5521
5522   abort_libfunc = init_one_libfunc ("abort");
5523   memcpy_libfunc = init_one_libfunc ("memcpy");
5524   memmove_libfunc = init_one_libfunc ("memmove");
5525   bcopy_libfunc = init_one_libfunc ("bcopy");
5526   memcmp_libfunc = init_one_libfunc ("memcmp");
5527   bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5528   memset_libfunc = init_one_libfunc ("memset");
5529   bzero_libfunc = init_one_libfunc ("bzero");
5530   setbits_libfunc = init_one_libfunc ("__setbits");
5531
5532   unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5533                                             ? "_Unwind_SjLj_Resume"
5534                                             : "_Unwind_Resume");
5535 #ifndef DONT_USE_BUILTIN_SETJMP
5536   setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5537   longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5538 #else
5539   setjmp_libfunc = init_one_libfunc ("setjmp");
5540   longjmp_libfunc = init_one_libfunc ("longjmp");
5541 #endif
5542   unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5543   unwind_sjlj_unregister_libfunc
5544     = init_one_libfunc ("_Unwind_SjLj_Unregister");
5545
5546   /* For function entry/exit instrumentation.  */
5547   profile_function_entry_libfunc
5548     = init_one_libfunc ("__cyg_profile_func_enter");
5549   profile_function_exit_libfunc
5550     = init_one_libfunc ("__cyg_profile_func_exit");
5551
5552   gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5553   gcov_init_libfunc = init_one_libfunc ("__gcov_init");
5554
5555   if (HAVE_conditional_trap)
5556     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5557
5558   /* Allow the target to add more libcalls or rename some, etc.  */
5559   targetm.init_libfuncs ();
5560 }
5561 \f
5562 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5563    CODE.  Return 0 on failure.  */
5564
5565 rtx
5566 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5567                rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5568 {
5569   enum machine_mode mode = GET_MODE (op1);
5570   enum insn_code icode;
5571   rtx insn;
5572
5573   if (!HAVE_conditional_trap)
5574     return 0;
5575
5576   if (mode == VOIDmode)
5577     return 0;
5578
5579   icode = cmp_optab->handlers[(int) mode].insn_code;
5580   if (icode == CODE_FOR_nothing)
5581     return 0;
5582
5583   start_sequence ();
5584   op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5585   op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5586   if (!op1 || !op2)
5587     {
5588       end_sequence ();
5589       return 0;
5590     }
5591   emit_insn (GEN_FCN (icode) (op1, op2));
5592
5593   PUT_CODE (trap_rtx, code);
5594   insn = gen_conditional_trap (trap_rtx, tcode);
5595   if (insn)
5596     {
5597       emit_insn (insn);
5598       insn = get_insns ();
5599     }
5600   end_sequence ();
5601
5602   return insn;
5603 }
5604
5605 #include "gt-optabs.h"