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