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