OSDN Git Service

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