OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [optabs.c] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* 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, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
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
#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
58
__extension__ struct optab_d optab_table[OTI_MAX]
59
  = { [0 ... OTI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1].insn_code
60
      = CODE_FOR_nothing };
61
#else
62
/* init_insn_codes will do runtime initialization otherwise.  */
63
struct optab_d optab_table[OTI_MAX];
64
#endif
65
 
66
rtx libfunc_table[LTI_MAX];
67
 
68
/* Tables of patterns for converting one mode to another.  */
69
#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
70
__extension__ struct convert_optab_d convert_optab_table[COI_MAX]
71
  = { [0 ... COI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1]
72
        [0 ... NUM_MACHINE_MODES - 1].insn_code
73
      = CODE_FOR_nothing };
74
#else
75
/* init_convert_optab will do runtime initialization otherwise.  */
76
struct convert_optab_d convert_optab_table[COI_MAX];
77
#endif
78
 
79
/* Contains the optab used for each rtx code.  */
80
optab code_to_optab[NUM_RTX_CODE + 1];
81
 
82
#ifdef HAVE_conditional_move
83
/* Indexed by the machine mode, gives the insn code to make a conditional
84
   move insn.  This is not indexed by the rtx-code like bcc_gen_fctn and
85
   setcc_gen_code to cut down on the number of named patterns.  Consider a day
86
   when a lot more rtx codes are conditional (eg: for the ARM).  */
87
 
88
enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
89
#endif
90
 
91
/* Indexed by the machine mode, gives the insn code for vector conditional
92
   operation.  */
93
 
94
enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
95
enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
96
 
97
static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
98
                                   enum machine_mode *);
99
static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
100
 
101
/* Debug facility for use in GDB.  */
102
void debug_optab_libfuncs (void);
103
 
104
/* Prefixes for the current version of decimal floating point (BID vs. DPD) */
105
#if ENABLE_DECIMAL_BID_FORMAT
106
#define DECIMAL_PREFIX "bid_"
107
#else
108
#define DECIMAL_PREFIX "dpd_"
109
#endif
110
 
111
 
112
/* Info about libfunc.  We use same hashtable for normal optabs and conversion
113
   optab.  In the first case mode2 is unused.  */
114
struct GTY(()) libfunc_entry {
115
  size_t optab;
116
  enum machine_mode mode1, mode2;
117
  rtx libfunc;
118
};
119
 
120
/* Hash table used to convert declarations into nodes.  */
121
static GTY((param_is (struct libfunc_entry))) htab_t libfunc_hash;
122
 
123
/* Used for attribute_hash.  */
124
 
125
static hashval_t
126
hash_libfunc (const void *p)
127
{
128
  const struct libfunc_entry *const e = (const struct libfunc_entry *) p;
129
 
130
  return (((int) e->mode1 + (int) e->mode2 * NUM_MACHINE_MODES)
131
          ^ e->optab);
132
}
133
 
134
/* Used for optab_hash.  */
135
 
136
static int
137
eq_libfunc (const void *p, const void *q)
138
{
139
  const struct libfunc_entry *const e1 = (const struct libfunc_entry *) p;
140
  const struct libfunc_entry *const e2 = (const struct libfunc_entry *) q;
141
 
142
  return (e1->optab == e2->optab
143
          && e1->mode1 == e2->mode1
144
          && e1->mode2 == e2->mode2);
145
}
146
 
147
/* Return libfunc corresponding operation defined by OPTAB converting
148
   from MODE2 to MODE1.  Trigger lazy initialization if needed, return NULL
149
   if no libfunc is available.  */
150
rtx
151
convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
152
                       enum machine_mode mode2)
153
{
154
  struct libfunc_entry e;
155
  struct libfunc_entry **slot;
156
 
157
  e.optab = (size_t) (optab - &convert_optab_table[0]);
158
  e.mode1 = mode1;
159
  e.mode2 = mode2;
160
  slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
161
  if (!slot)
162
    {
163
      if (optab->libcall_gen)
164
        {
165
          optab->libcall_gen (optab, optab->libcall_basename, mode1, mode2);
166
          slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
167
          if (slot)
168
            return (*slot)->libfunc;
169
          else
170
            return NULL;
171
        }
172
      return NULL;
173
    }
174
  return (*slot)->libfunc;
175
}
176
 
177
/* Return libfunc corresponding operation defined by OPTAB in MODE.
178
   Trigger lazy initialization if needed, return NULL if no libfunc is
179
   available.  */
180
rtx
181
optab_libfunc (optab optab, enum machine_mode mode)
182
{
183
  struct libfunc_entry e;
184
  struct libfunc_entry **slot;
185
 
186
  e.optab = (size_t) (optab - &optab_table[0]);
187
  e.mode1 = mode;
188
  e.mode2 = VOIDmode;
189
  slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, NO_INSERT);
190
  if (!slot)
191
    {
192
      if (optab->libcall_gen)
193
        {
194
          optab->libcall_gen (optab, optab->libcall_basename,
195
                              optab->libcall_suffix, mode);
196
          slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash,
197
                                                           &e, NO_INSERT);
198
          if (slot)
199
            return (*slot)->libfunc;
200
          else
201
            return NULL;
202
        }
203
      return NULL;
204
    }
205
  return (*slot)->libfunc;
206
}
207
 
208
 
209
/* Add a REG_EQUAL note to the last insn in INSNS.  TARGET is being set to
210
   the result of operation CODE applied to OP0 (and OP1 if it is a binary
211
   operation).
212
 
213
   If the last insn does not set TARGET, don't do anything, but return 1.
214
 
215
   If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
216
   don't add the REG_EQUAL note but return 0.  Our caller can then try
217
   again, ensuring that TARGET is not one of the operands.  */
218
 
219
static int
220
add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
221
{
222
  rtx last_insn, insn, set;
223
  rtx note;
224
 
225
  gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
226
 
227
  if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
228
      && GET_RTX_CLASS (code) != RTX_BIN_ARITH
229
      && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
230
      && GET_RTX_CLASS (code) != RTX_COMPARE
231
      && GET_RTX_CLASS (code) != RTX_UNARY)
232
    return 1;
233
 
234
  if (GET_CODE (target) == ZERO_EXTRACT)
235
    return 1;
236
 
237
  for (last_insn = insns;
238
       NEXT_INSN (last_insn) != NULL_RTX;
239
       last_insn = NEXT_INSN (last_insn))
240
    ;
241
 
242
  set = single_set (last_insn);
243
  if (set == NULL_RTX)
244
    return 1;
245
 
246
  if (! rtx_equal_p (SET_DEST (set), target)
247
      /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it.  */
248
      && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
249
          || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
250
    return 1;
251
 
252
  /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
253
     besides the last insn.  */
254
  if (reg_overlap_mentioned_p (target, op0)
255
      || (op1 && reg_overlap_mentioned_p (target, op1)))
256
    {
257
      insn = PREV_INSN (last_insn);
258
      while (insn != NULL_RTX)
259
        {
260
          if (reg_set_p (target, insn))
261
            return 0;
262
 
263
          insn = PREV_INSN (insn);
264
        }
265
    }
266
 
267
  if (GET_RTX_CLASS (code) == RTX_UNARY)
268
    note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
269
  else
270
    note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
271
 
272
  set_unique_reg_note (last_insn, REG_EQUAL, note);
273
 
274
  return 1;
275
}
276
 
277
/* Widen OP to MODE and return the rtx for the widened operand.  UNSIGNEDP
278
   says whether OP is signed or unsigned.  NO_EXTEND is nonzero if we need
279
   not actually do a sign-extend or zero-extend, but can leave the
280
   higher-order bits of the result rtx undefined, for example, in the case
281
   of logical operations, but not right shifts.  */
282
 
283
static rtx
284
widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
285
               int unsignedp, int no_extend)
286
{
287
  rtx result;
288
 
289
  /* If we don't have to extend and this is a constant, return it.  */
290
  if (no_extend && GET_MODE (op) == VOIDmode)
291
    return op;
292
 
293
  /* If we must extend do so.  If OP is a SUBREG for a promoted object, also
294
     extend since it will be more efficient to do so unless the signedness of
295
     a promoted object differs from our extension.  */
296
  if (! no_extend
297
      || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
298
          && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
299
    return convert_modes (mode, oldmode, op, unsignedp);
300
 
301
  /* If MODE is no wider than a single word, we return a paradoxical
302
     SUBREG.  */
303
  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
304
    return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
305
 
306
  /* Otherwise, get an object of MODE, clobber it, and set the low-order
307
     part to OP.  */
308
 
309
  result = gen_reg_rtx (mode);
310
  emit_clobber (result);
311
  emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
312
  return result;
313
}
314
 
315
/* Return the optab used for computing the operation given by the tree code,
316
   CODE and the tree EXP.  This function is not always usable (for example, it
317
   cannot give complete results for multiplication or division) but probably
318
   ought to be relied on more widely throughout the expander.  */
319
optab
320
optab_for_tree_code (enum tree_code code, const_tree type,
321
                     enum optab_subtype subtype)
322
{
323
  bool trapv;
324
  switch (code)
325
    {
326
    case BIT_AND_EXPR:
327
      return and_optab;
328
 
329
    case BIT_IOR_EXPR:
330
      return ior_optab;
331
 
332
    case BIT_NOT_EXPR:
333
      return one_cmpl_optab;
334
 
335
    case BIT_XOR_EXPR:
336
      return xor_optab;
337
 
338
    case TRUNC_MOD_EXPR:
339
    case CEIL_MOD_EXPR:
340
    case FLOOR_MOD_EXPR:
341
    case ROUND_MOD_EXPR:
342
      return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
343
 
344
    case RDIV_EXPR:
345
    case TRUNC_DIV_EXPR:
346
    case CEIL_DIV_EXPR:
347
    case FLOOR_DIV_EXPR:
348
    case ROUND_DIV_EXPR:
349
    case EXACT_DIV_EXPR:
350
      if (TYPE_SATURATING(type))
351
        return TYPE_UNSIGNED(type) ? usdiv_optab : ssdiv_optab;
352
      return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
353
 
354
    case LSHIFT_EXPR:
355
      if (VECTOR_MODE_P (TYPE_MODE (type)))
356
        {
357
          if (subtype == optab_vector)
358
            return TYPE_SATURATING (type) ? NULL : vashl_optab;
359
 
360
          gcc_assert (subtype == optab_scalar);
361
        }
362
      if (TYPE_SATURATING(type))
363
        return TYPE_UNSIGNED(type) ? usashl_optab : ssashl_optab;
364
      return ashl_optab;
365
 
366
    case RSHIFT_EXPR:
367
      if (VECTOR_MODE_P (TYPE_MODE (type)))
368
        {
369
          if (subtype == optab_vector)
370
            return TYPE_UNSIGNED (type) ? vlshr_optab : vashr_optab;
371
 
372
          gcc_assert (subtype == optab_scalar);
373
        }
374
      return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
375
 
376
    case LROTATE_EXPR:
377
      if (VECTOR_MODE_P (TYPE_MODE (type)))
378
        {
379
          if (subtype == optab_vector)
380
            return vrotl_optab;
381
 
382
          gcc_assert (subtype == optab_scalar);
383
        }
384
      return rotl_optab;
385
 
386
    case RROTATE_EXPR:
387
      if (VECTOR_MODE_P (TYPE_MODE (type)))
388
        {
389
          if (subtype == optab_vector)
390
            return vrotr_optab;
391
 
392
          gcc_assert (subtype == optab_scalar);
393
        }
394
      return rotr_optab;
395
 
396
    case MAX_EXPR:
397
      return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
398
 
399
    case MIN_EXPR:
400
      return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
401
 
402
    case REALIGN_LOAD_EXPR:
403
      return vec_realign_load_optab;
404
 
405
    case WIDEN_SUM_EXPR:
406
      return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
407
 
408
    case DOT_PROD_EXPR:
409
      return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
410
 
411
    case REDUC_MAX_EXPR:
412
      return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
413
 
414
    case REDUC_MIN_EXPR:
415
      return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
416
 
417
    case REDUC_PLUS_EXPR:
418
      return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
419
 
420
    case VEC_LSHIFT_EXPR:
421
      return vec_shl_optab;
422
 
423
    case VEC_RSHIFT_EXPR:
424
      return vec_shr_optab;
425
 
426
    case VEC_WIDEN_MULT_HI_EXPR:
427
      return TYPE_UNSIGNED (type) ?
428
        vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
429
 
430
    case VEC_WIDEN_MULT_LO_EXPR:
431
      return TYPE_UNSIGNED (type) ?
432
        vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
433
 
434
    case VEC_UNPACK_HI_EXPR:
435
      return TYPE_UNSIGNED (type) ?
436
        vec_unpacku_hi_optab : vec_unpacks_hi_optab;
437
 
438
    case VEC_UNPACK_LO_EXPR:
439
      return TYPE_UNSIGNED (type) ?
440
        vec_unpacku_lo_optab : vec_unpacks_lo_optab;
441
 
442
    case VEC_UNPACK_FLOAT_HI_EXPR:
443
      /* The signedness is determined from input operand.  */
444
      return TYPE_UNSIGNED (type) ?
445
        vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
446
 
447
    case VEC_UNPACK_FLOAT_LO_EXPR:
448
      /* The signedness is determined from input operand.  */
449
      return TYPE_UNSIGNED (type) ?
450
        vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
451
 
452
    case VEC_PACK_TRUNC_EXPR:
453
      return vec_pack_trunc_optab;
454
 
455
    case VEC_PACK_SAT_EXPR:
456
      return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
457
 
458
    case VEC_PACK_FIX_TRUNC_EXPR:
459
      /* The signedness is determined from output operand.  */
460
      return TYPE_UNSIGNED (type) ?
461
        vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
462
 
463
    default:
464
      break;
465
    }
466
 
467
  trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
468
  switch (code)
469
    {
470
    case POINTER_PLUS_EXPR:
471
    case PLUS_EXPR:
472
      if (TYPE_SATURATING(type))
473
        return TYPE_UNSIGNED(type) ? usadd_optab : ssadd_optab;
474
      return trapv ? addv_optab : add_optab;
475
 
476
    case MINUS_EXPR:
477
      if (TYPE_SATURATING(type))
478
        return TYPE_UNSIGNED(type) ? ussub_optab : sssub_optab;
479
      return trapv ? subv_optab : sub_optab;
480
 
481
    case MULT_EXPR:
482
      if (TYPE_SATURATING(type))
483
        return TYPE_UNSIGNED(type) ? usmul_optab : ssmul_optab;
484
      return trapv ? smulv_optab : smul_optab;
485
 
486
    case NEGATE_EXPR:
487
      if (TYPE_SATURATING(type))
488
        return TYPE_UNSIGNED(type) ? usneg_optab : ssneg_optab;
489
      return trapv ? negv_optab : neg_optab;
490
 
491
    case ABS_EXPR:
492
      return trapv ? absv_optab : abs_optab;
493
 
494
    case VEC_EXTRACT_EVEN_EXPR:
495
      return vec_extract_even_optab;
496
 
497
    case VEC_EXTRACT_ODD_EXPR:
498
      return vec_extract_odd_optab;
499
 
500
    case VEC_INTERLEAVE_HIGH_EXPR:
501
      return vec_interleave_high_optab;
502
 
503
    case VEC_INTERLEAVE_LOW_EXPR:
504
      return vec_interleave_low_optab;
505
 
506
    default:
507
      return NULL;
508
    }
509
}
510
 
511
 
512
/* Expand vector widening operations.
513
 
514
   There are two different classes of operations handled here:
515
   1) Operations whose result is wider than all the arguments to the operation.
516
      Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
517
      In this case OP0 and optionally OP1 would be initialized,
518
      but WIDE_OP wouldn't (not relevant for this case).
519
   2) Operations whose result is of the same size as the last argument to the
520
      operation, but wider than all the other arguments to the operation.
521
      Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
522
      In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
523
 
524
   E.g, when called to expand the following operations, this is how
525
   the arguments will be initialized:
526
                                nops    OP0     OP1     WIDE_OP
527
   widening-sum                 2       oprnd0  -       oprnd1
528
   widening-dot-product         3       oprnd0  oprnd1  oprnd2
529
   widening-mult                2       oprnd0  oprnd1  -
530
   type-promotion (vec-unpack)  1       oprnd0  -       -  */
531
 
532
rtx
533
expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
534
                           rtx target, int unsignedp)
535
{
536
  tree oprnd0, oprnd1, oprnd2;
537
  enum machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
538
  optab widen_pattern_optab;
539
  int icode;
540
  enum machine_mode xmode0, xmode1 = VOIDmode, wxmode = VOIDmode;
541
  rtx temp;
542
  rtx pat;
543
  rtx xop0, xop1, wxop;
544
  int nops = TREE_CODE_LENGTH (ops->code);
545
 
546
  oprnd0 = ops->op0;
547
  tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
548
  widen_pattern_optab =
549
    optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
550
  icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code;
551
  gcc_assert (icode != CODE_FOR_nothing);
552
  xmode0 = insn_data[icode].operand[1].mode;
553
 
554
  if (nops >= 2)
555
    {
556
      oprnd1 = ops->op1;
557
      tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
558
      xmode1 = insn_data[icode].operand[2].mode;
559
    }
560
 
561
  /* The last operand is of a wider mode than the rest of the operands.  */
562
  if (nops == 2)
563
    {
564
      wmode = tmode1;
565
      wxmode = xmode1;
566
    }
567
  else if (nops == 3)
568
    {
569
      gcc_assert (tmode1 == tmode0);
570
      gcc_assert (op1);
571
      oprnd2 = ops->op2;
572
      wmode = TYPE_MODE (TREE_TYPE (oprnd2));
573
      wxmode = insn_data[icode].operand[3].mode;
574
    }
575
 
576
  if (!wide_op)
577
    wmode = wxmode = insn_data[icode].operand[0].mode;
578
 
579
  if (!target
580
      || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
581
    temp = gen_reg_rtx (wmode);
582
  else
583
    temp = target;
584
 
585
  xop0 = op0;
586
  xop1 = op1;
587
  wxop = wide_op;
588
 
589
  /* In case the insn wants input operands in modes different from
590
     those of the actual operands, convert the operands.  It would
591
     seem that we don't need to convert CONST_INTs, but we do, so
592
     that they're properly zero-extended, sign-extended or truncated
593
     for their mode.  */
594
 
595
  if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
596
    xop0 = convert_modes (xmode0,
597
                          GET_MODE (op0) != VOIDmode
598
                          ? GET_MODE (op0)
599
                          : tmode0,
600
                          xop0, unsignedp);
601
 
602
  if (op1)
603
    if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
604
      xop1 = convert_modes (xmode1,
605
                            GET_MODE (op1) != VOIDmode
606
                            ? GET_MODE (op1)
607
                            : tmode1,
608
                            xop1, unsignedp);
609
 
610
  if (wide_op)
611
    if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
612
      wxop = convert_modes (wxmode,
613
                            GET_MODE (wide_op) != VOIDmode
614
                            ? GET_MODE (wide_op)
615
                            : wmode,
616
                            wxop, unsignedp);
617
 
618
  /* Now, if insn's predicates don't allow our operands, put them into
619
     pseudo regs.  */
620
 
621
  if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
622
      && xmode0 != VOIDmode)
623
    xop0 = copy_to_mode_reg (xmode0, xop0);
624
 
625
  if (op1)
626
    {
627
      if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
628
          && xmode1 != VOIDmode)
629
        xop1 = copy_to_mode_reg (xmode1, xop1);
630
 
631
      if (wide_op)
632
        {
633
          if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
634
              && wxmode != VOIDmode)
635
            wxop = copy_to_mode_reg (wxmode, wxop);
636
 
637
          pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
638
        }
639
      else
640
        pat = GEN_FCN (icode) (temp, xop0, xop1);
641
    }
642
  else
643
    {
644
      if (wide_op)
645
        {
646
          if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
647
              && wxmode != VOIDmode)
648
            wxop = copy_to_mode_reg (wxmode, wxop);
649
 
650
          pat = GEN_FCN (icode) (temp, xop0, wxop);
651
        }
652
      else
653
        pat = GEN_FCN (icode) (temp, xop0);
654
    }
655
 
656
  emit_insn (pat);
657
  return temp;
658
}
659
 
660
/* Generate code to perform an operation specified by TERNARY_OPTAB
661
   on operands OP0, OP1 and OP2, with result having machine-mode MODE.
662
 
663
   UNSIGNEDP is for the case where we have to widen the operands
664
   to perform the operation.  It says to use zero-extension.
665
 
666
   If TARGET is nonzero, the value
667
   is generated there, if it is convenient to do so.
668
   In all cases an rtx is returned for the locus of the value;
669
   this may or may not be TARGET.  */
670
 
671
rtx
672
expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
673
                   rtx op1, rtx op2, rtx target, int unsignedp)
674
{
675
  int icode = (int) optab_handler (ternary_optab, mode)->insn_code;
676
  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
677
  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
678
  enum machine_mode mode2 = insn_data[icode].operand[3].mode;
679
  rtx temp;
680
  rtx pat;
681
  rtx xop0 = op0, xop1 = op1, xop2 = op2;
682
 
683
  gcc_assert (optab_handler (ternary_optab, mode)->insn_code
684
              != CODE_FOR_nothing);
685
 
686
  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
687
    temp = gen_reg_rtx (mode);
688
  else
689
    temp = target;
690
 
691
  /* In case the insn wants input operands in modes different from
692
     those of the actual operands, convert the operands.  It would
693
     seem that we don't need to convert CONST_INTs, but we do, so
694
     that they're properly zero-extended, sign-extended or truncated
695
     for their mode.  */
696
 
697
  if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
698
    xop0 = convert_modes (mode0,
699
                          GET_MODE (op0) != VOIDmode
700
                          ? GET_MODE (op0)
701
                          : mode,
702
                          xop0, unsignedp);
703
 
704
  if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
705
    xop1 = convert_modes (mode1,
706
                          GET_MODE (op1) != VOIDmode
707
                          ? GET_MODE (op1)
708
                          : mode,
709
                          xop1, unsignedp);
710
 
711
  if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
712
    xop2 = convert_modes (mode2,
713
                          GET_MODE (op2) != VOIDmode
714
                          ? GET_MODE (op2)
715
                          : mode,
716
                          xop2, unsignedp);
717
 
718
  /* Now, if insn's predicates don't allow our operands, put them into
719
     pseudo regs.  */
720
 
721
  if (!insn_data[icode].operand[1].predicate (xop0, mode0)
722
      && mode0 != VOIDmode)
723
    xop0 = copy_to_mode_reg (mode0, xop0);
724
 
725
  if (!insn_data[icode].operand[2].predicate (xop1, mode1)
726
      && mode1 != VOIDmode)
727
    xop1 = copy_to_mode_reg (mode1, xop1);
728
 
729
  if (!insn_data[icode].operand[3].predicate (xop2, mode2)
730
      && mode2 != VOIDmode)
731
    xop2 = copy_to_mode_reg (mode2, xop2);
732
 
733
  pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
734
 
735
  emit_insn (pat);
736
  return temp;
737
}
738
 
739
 
740
/* Like expand_binop, but return a constant rtx if the result can be
741
   calculated at compile time.  The arguments and return value are
742
   otherwise the same as for expand_binop.  */
743
 
744
static rtx
745
simplify_expand_binop (enum machine_mode mode, optab binoptab,
746
                       rtx op0, rtx op1, rtx target, int unsignedp,
747
                       enum optab_methods methods)
748
{
749
  if (CONSTANT_P (op0) && CONSTANT_P (op1))
750
    {
751
      rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
752
 
753
      if (x)
754
        return x;
755
    }
756
 
757
  return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
758
}
759
 
760
/* Like simplify_expand_binop, but always put the result in TARGET.
761
   Return true if the expansion succeeded.  */
762
 
763
bool
764
force_expand_binop (enum machine_mode mode, optab binoptab,
765
                    rtx op0, rtx op1, rtx target, int unsignedp,
766
                    enum optab_methods methods)
767
{
768
  rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
769
                                 target, unsignedp, methods);
770
  if (x == 0)
771
    return false;
772
  if (x != target)
773
    emit_move_insn (target, x);
774
  return true;
775
}
776
 
777
/* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR.  */
778
 
779
rtx
780
expand_vec_shift_expr (sepops ops, rtx target)
781
{
782
  enum insn_code icode;
783
  rtx rtx_op1, rtx_op2;
784
  enum machine_mode mode1;
785
  enum machine_mode mode2;
786
  enum machine_mode mode = TYPE_MODE (ops->type);
787
  tree vec_oprnd = ops->op0;
788
  tree shift_oprnd = ops->op1;
789
  optab shift_optab;
790
  rtx pat;
791
 
792
  switch (ops->code)
793
    {
794
      case VEC_RSHIFT_EXPR:
795
        shift_optab = vec_shr_optab;
796
        break;
797
      case VEC_LSHIFT_EXPR:
798
        shift_optab = vec_shl_optab;
799
        break;
800
      default:
801
        gcc_unreachable ();
802
    }
803
 
804
  icode = optab_handler (shift_optab, mode)->insn_code;
805
  gcc_assert (icode != CODE_FOR_nothing);
806
 
807
  mode1 = insn_data[icode].operand[1].mode;
808
  mode2 = insn_data[icode].operand[2].mode;
809
 
810
  rtx_op1 = expand_normal (vec_oprnd);
811
  if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
812
      && mode1 != VOIDmode)
813
    rtx_op1 = force_reg (mode1, rtx_op1);
814
 
815
  rtx_op2 = expand_normal (shift_oprnd);
816
  if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
817
      && mode2 != VOIDmode)
818
    rtx_op2 = force_reg (mode2, rtx_op2);
819
 
820
  if (!target
821
      || ! (*insn_data[icode].operand[0].predicate) (target, mode))
822
    target = gen_reg_rtx (mode);
823
 
824
  /* Emit instruction */
825
  pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
826
  gcc_assert (pat);
827
  emit_insn (pat);
828
 
829
  return target;
830
}
831
 
832
/* This subroutine of expand_doubleword_shift handles the cases in which
833
   the effective shift value is >= BITS_PER_WORD.  The arguments and return
834
   value are the same as for the parent routine, except that SUPERWORD_OP1
835
   is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
836
   INTO_TARGET may be null if the caller has decided to calculate it.  */
837
 
838
static bool
839
expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
840
                        rtx outof_target, rtx into_target,
841
                        int unsignedp, enum optab_methods methods)
842
{
843
  if (into_target != 0)
844
    if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
845
                             into_target, unsignedp, methods))
846
      return false;
847
 
848
  if (outof_target != 0)
849
    {
850
      /* For a signed right shift, we must fill OUTOF_TARGET with copies
851
         of the sign bit, otherwise we must fill it with zeros.  */
852
      if (binoptab != ashr_optab)
853
        emit_move_insn (outof_target, CONST0_RTX (word_mode));
854
      else
855
        if (!force_expand_binop (word_mode, binoptab,
856
                                 outof_input, GEN_INT (BITS_PER_WORD - 1),
857
                                 outof_target, unsignedp, methods))
858
          return false;
859
    }
860
  return true;
861
}
862
 
863
/* This subroutine of expand_doubleword_shift handles the cases in which
864
   the effective shift value is < BITS_PER_WORD.  The arguments and return
865
   value are the same as for the parent routine.  */
866
 
867
static bool
868
expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
869
                      rtx outof_input, rtx into_input, rtx op1,
870
                      rtx outof_target, rtx into_target,
871
                      int unsignedp, enum optab_methods methods,
872
                      unsigned HOST_WIDE_INT shift_mask)
873
{
874
  optab reverse_unsigned_shift, unsigned_shift;
875
  rtx tmp, carries;
876
 
877
  reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
878
  unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
879
 
880
  /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
881
     We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
882
     the opposite direction to BINOPTAB.  */
883
  if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
884
    {
885
      carries = outof_input;
886
      tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
887
      tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
888
                                   0, true, methods);
889
    }
890
  else
891
    {
892
      /* We must avoid shifting by BITS_PER_WORD bits since that is either
893
         the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
894
         has unknown behavior.  Do a single shift first, then shift by the
895
         remainder.  It's OK to use ~OP1 as the remainder if shift counts
896
         are truncated to the mode size.  */
897
      carries = expand_binop (word_mode, reverse_unsigned_shift,
898
                              outof_input, const1_rtx, 0, unsignedp, methods);
899
      if (shift_mask == BITS_PER_WORD - 1)
900
        {
901
          tmp = immed_double_const (-1, -1, op1_mode);
902
          tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
903
                                       0, true, methods);
904
        }
905
      else
906
        {
907
          tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
908
          tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
909
                                       0, true, methods);
910
        }
911
    }
912
  if (tmp == 0 || carries == 0)
913
    return false;
914
  carries = expand_binop (word_mode, reverse_unsigned_shift,
915
                          carries, tmp, 0, unsignedp, methods);
916
  if (carries == 0)
917
    return false;
918
 
919
  /* Shift INTO_INPUT logically by OP1.  This is the last use of INTO_INPUT
920
     so the result can go directly into INTO_TARGET if convenient.  */
921
  tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
922
                      into_target, unsignedp, methods);
923
  if (tmp == 0)
924
    return false;
925
 
926
  /* Now OR in the bits carried over from OUTOF_INPUT.  */
927
  if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
928
                           into_target, unsignedp, methods))
929
    return false;
930
 
931
  /* Use a standard word_mode shift for the out-of half.  */
932
  if (outof_target != 0)
933
    if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
934
                             outof_target, unsignedp, methods))
935
      return false;
936
 
937
  return true;
938
}
939
 
940
 
941
#ifdef HAVE_conditional_move
942
/* Try implementing expand_doubleword_shift using conditional moves.
943
   The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
944
   otherwise it is by >= BITS_PER_WORD.  SUBWORD_OP1 and SUPERWORD_OP1
945
   are the shift counts to use in the former and latter case.  All other
946
   arguments are the same as the parent routine.  */
947
 
948
static bool
949
expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
950
                                  enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
951
                                  rtx outof_input, rtx into_input,
952
                                  rtx subword_op1, rtx superword_op1,
953
                                  rtx outof_target, rtx into_target,
954
                                  int unsignedp, enum optab_methods methods,
955
                                  unsigned HOST_WIDE_INT shift_mask)
956
{
957
  rtx outof_superword, into_superword;
958
 
959
  /* Put the superword version of the output into OUTOF_SUPERWORD and
960
     INTO_SUPERWORD.  */
961
  outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
962
  if (outof_target != 0 && subword_op1 == superword_op1)
963
    {
964
      /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
965
         OUTOF_TARGET, is the same as the value of INTO_SUPERWORD.  */
966
      into_superword = outof_target;
967
      if (!expand_superword_shift (binoptab, outof_input, superword_op1,
968
                                   outof_superword, 0, unsignedp, methods))
969
        return false;
970
    }
971
  else
972
    {
973
      into_superword = gen_reg_rtx (word_mode);
974
      if (!expand_superword_shift (binoptab, outof_input, superword_op1,
975
                                   outof_superword, into_superword,
976
                                   unsignedp, methods))
977
        return false;
978
    }
979
 
980
  /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET.  */
981
  if (!expand_subword_shift (op1_mode, binoptab,
982
                             outof_input, into_input, subword_op1,
983
                             outof_target, into_target,
984
                             unsignedp, methods, shift_mask))
985
    return false;
986
 
987
  /* Select between them.  Do the INTO half first because INTO_SUPERWORD
988
     might be the current value of OUTOF_TARGET.  */
989
  if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
990
                              into_target, into_superword, word_mode, false))
991
    return false;
992
 
993
  if (outof_target != 0)
994
    if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
995
                                outof_target, outof_superword,
996
                                word_mode, false))
997
      return false;
998
 
999
  return true;
1000
}
1001
#endif
1002
 
1003
/* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
1004
   OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
1005
   input operand; the shift moves bits in the direction OUTOF_INPUT->
1006
   INTO_TARGET.  OUTOF_TARGET and INTO_TARGET are the equivalent words
1007
   of the target.  OP1 is the shift count and OP1_MODE is its mode.
1008
   If OP1 is constant, it will have been truncated as appropriate
1009
   and is known to be nonzero.
1010
 
1011
   If SHIFT_MASK is zero, the result of word shifts is undefined when the
1012
   shift count is outside the range [0, BITS_PER_WORD).  This routine must
1013
   avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
1014
 
1015
   If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
1016
   masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
1017
   fill with zeros or sign bits as appropriate.
1018
 
1019
   If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
1020
   a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
1021
   Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
1022
   In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
1023
   are undefined.
1024
 
1025
   BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop.  This function
1026
   may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
1027
   OUTOF_INPUT and OUTOF_TARGET.  OUTOF_TARGET can be null if the parent
1028
   function wants to calculate it itself.
1029
 
1030
   Return true if the shift could be successfully synthesized.  */
1031
 
1032
static bool
1033
expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
1034
                         rtx outof_input, rtx into_input, rtx op1,
1035
                         rtx outof_target, rtx into_target,
1036
                         int unsignedp, enum optab_methods methods,
1037
                         unsigned HOST_WIDE_INT shift_mask)
1038
{
1039
  rtx superword_op1, tmp, cmp1, cmp2;
1040
  rtx subword_label, done_label;
1041
  enum rtx_code cmp_code;
1042
 
1043
  /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
1044
     fill the result with sign or zero bits as appropriate.  If so, the value
1045
     of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1).   Recursively call
1046
     this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
1047
     and INTO_INPUT), then emit code to set up OUTOF_TARGET.
1048
 
1049
     This isn't worthwhile for constant shifts since the optimizers will
1050
     cope better with in-range shift counts.  */
1051
  if (shift_mask >= BITS_PER_WORD
1052
      && outof_target != 0
1053
      && !CONSTANT_P (op1))
1054
    {
1055
      if (!expand_doubleword_shift (op1_mode, binoptab,
1056
                                    outof_input, into_input, op1,
1057
                                    0, into_target,
1058
                                    unsignedp, methods, shift_mask))
1059
        return false;
1060
      if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
1061
                               outof_target, unsignedp, methods))
1062
        return false;
1063
      return true;
1064
    }
1065
 
1066
  /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
1067
     is true when the effective shift value is less than BITS_PER_WORD.
1068
     Set SUPERWORD_OP1 to the shift count that should be used to shift
1069
     OUTOF_INPUT into INTO_TARGET when the condition is false.  */
1070
  tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
1071
  if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
1072
    {
1073
      /* Set CMP1 to OP1 & BITS_PER_WORD.  The result is zero iff OP1
1074
         is a subword shift count.  */
1075
      cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
1076
                                    0, true, methods);
1077
      cmp2 = CONST0_RTX (op1_mode);
1078
      cmp_code = EQ;
1079
      superword_op1 = op1;
1080
    }
1081
  else
1082
    {
1083
      /* Set CMP1 to OP1 - BITS_PER_WORD.  */
1084
      cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
1085
                                    0, true, methods);
1086
      cmp2 = CONST0_RTX (op1_mode);
1087
      cmp_code = LT;
1088
      superword_op1 = cmp1;
1089
    }
1090
  if (cmp1 == 0)
1091
    return false;
1092
 
1093
  /* If we can compute the condition at compile time, pick the
1094
     appropriate subroutine.  */
1095
  tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
1096
  if (tmp != 0 && CONST_INT_P (tmp))
1097
    {
1098
      if (tmp == const0_rtx)
1099
        return expand_superword_shift (binoptab, outof_input, superword_op1,
1100
                                       outof_target, into_target,
1101
                                       unsignedp, methods);
1102
      else
1103
        return expand_subword_shift (op1_mode, binoptab,
1104
                                     outof_input, into_input, op1,
1105
                                     outof_target, into_target,
1106
                                     unsignedp, methods, shift_mask);
1107
    }
1108
 
1109
#ifdef HAVE_conditional_move
1110
  /* Try using conditional moves to generate straight-line code.  */
1111
  {
1112
    rtx start = get_last_insn ();
1113
    if (expand_doubleword_shift_condmove (op1_mode, binoptab,
1114
                                          cmp_code, cmp1, cmp2,
1115
                                          outof_input, into_input,
1116
                                          op1, superword_op1,
1117
                                          outof_target, into_target,
1118
                                          unsignedp, methods, shift_mask))
1119
      return true;
1120
    delete_insns_since (start);
1121
  }
1122
#endif
1123
 
1124
  /* As a last resort, use branches to select the correct alternative.  */
1125
  subword_label = gen_label_rtx ();
1126
  done_label = gen_label_rtx ();
1127
 
1128
  NO_DEFER_POP;
1129
  do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1130
                           0, 0, subword_label, -1);
1131
  OK_DEFER_POP;
1132
 
1133
  if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1134
                               outof_target, into_target,
1135
                               unsignedp, methods))
1136
    return false;
1137
 
1138
  emit_jump_insn (gen_jump (done_label));
1139
  emit_barrier ();
1140
  emit_label (subword_label);
1141
 
1142
  if (!expand_subword_shift (op1_mode, binoptab,
1143
                             outof_input, into_input, op1,
1144
                             outof_target, into_target,
1145
                             unsignedp, methods, shift_mask))
1146
    return false;
1147
 
1148
  emit_label (done_label);
1149
  return true;
1150
}
1151
 
1152
/* Subroutine of expand_binop.  Perform a double word multiplication of
1153
   operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1154
   as the target's word_mode.  This function return NULL_RTX if anything
1155
   goes wrong, in which case it may have already emitted instructions
1156
   which need to be deleted.
1157
 
1158
   If we want to multiply two two-word values and have normal and widening
1159
   multiplies of single-word values, we can do this with three smaller
1160
   multiplications.
1161
 
1162
   The multiplication proceeds as follows:
1163
                                 _______________________
1164
                                [__op0_high_|__op0_low__]
1165
                                 _______________________
1166
        *                       [__op1_high_|__op1_low__]
1167
        _______________________________________________
1168
                                 _______________________
1169
    (1)                         [__op0_low__*__op1_low__]
1170
                     _______________________
1171
    (2a)            [__op0_low__*__op1_high_]
1172
                     _______________________
1173
    (2b)            [__op0_high_*__op1_low__]
1174
         _______________________
1175
    (3) [__op0_high_*__op1_high_]
1176
 
1177
 
1178
  This gives a 4-word result.  Since we are only interested in the
1179
  lower 2 words, partial result (3) and the upper words of (2a) and
1180
  (2b) don't need to be calculated.  Hence (2a) and (2b) can be
1181
  calculated using non-widening multiplication.
1182
 
1183
  (1), however, needs to be calculated with an unsigned widening
1184
  multiplication.  If this operation is not directly supported we
1185
  try using a signed widening multiplication and adjust the result.
1186
  This adjustment works as follows:
1187
 
1188
      If both operands are positive then no adjustment is needed.
1189
 
1190
      If the operands have different signs, for example op0_low < 0 and
1191
      op1_low >= 0, the instruction treats the most significant bit of
1192
      op0_low as a sign bit instead of a bit with significance
1193
      2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1194
      with 2**BITS_PER_WORD - op0_low, and two's complements the
1195
      result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1196
      the result.
1197
 
1198
      Similarly, if both operands are negative, we need to add
1199
      (op0_low + op1_low) * 2**BITS_PER_WORD.
1200
 
1201
      We use a trick to adjust quickly.  We logically shift op0_low right
1202
      (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1203
      op0_high (op1_high) before it is used to calculate 2b (2a).  If no
1204
      logical shift exists, we do an arithmetic right shift and subtract
1205
      the 0 or -1.  */
1206
 
1207
static rtx
1208
expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1209
                       bool umulp, enum optab_methods methods)
1210
{
1211
  int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1212
  int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1213
  rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1214
  rtx product, adjust, product_high, temp;
1215
 
1216
  rtx op0_high = operand_subword_force (op0, high, mode);
1217
  rtx op0_low = operand_subword_force (op0, low, mode);
1218
  rtx op1_high = operand_subword_force (op1, high, mode);
1219
  rtx op1_low = operand_subword_force (op1, low, mode);
1220
 
1221
  /* If we're using an unsigned multiply to directly compute the product
1222
     of the low-order words of the operands and perform any required
1223
     adjustments of the operands, we begin by trying two more multiplications
1224
     and then computing the appropriate sum.
1225
 
1226
     We have checked above that the required addition is provided.
1227
     Full-word addition will normally always succeed, especially if
1228
     it is provided at all, so we don't worry about its failure.  The
1229
     multiplication may well fail, however, so we do handle that.  */
1230
 
1231
  if (!umulp)
1232
    {
1233
      /* ??? This could be done with emit_store_flag where available.  */
1234
      temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1235
                           NULL_RTX, 1, methods);
1236
      if (temp)
1237
        op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1238
                                 NULL_RTX, 0, OPTAB_DIRECT);
1239
      else
1240
        {
1241
          temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1242
                               NULL_RTX, 0, methods);
1243
          if (!temp)
1244
            return NULL_RTX;
1245
          op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1246
                                   NULL_RTX, 0, OPTAB_DIRECT);
1247
        }
1248
 
1249
      if (!op0_high)
1250
        return NULL_RTX;
1251
    }
1252
 
1253
  adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1254
                         NULL_RTX, 0, OPTAB_DIRECT);
1255
  if (!adjust)
1256
    return NULL_RTX;
1257
 
1258
  /* OP0_HIGH should now be dead.  */
1259
 
1260
  if (!umulp)
1261
    {
1262
      /* ??? This could be done with emit_store_flag where available.  */
1263
      temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1264
                           NULL_RTX, 1, methods);
1265
      if (temp)
1266
        op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1267
                                 NULL_RTX, 0, OPTAB_DIRECT);
1268
      else
1269
        {
1270
          temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1271
                               NULL_RTX, 0, methods);
1272
          if (!temp)
1273
            return NULL_RTX;
1274
          op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1275
                                   NULL_RTX, 0, OPTAB_DIRECT);
1276
        }
1277
 
1278
      if (!op1_high)
1279
        return NULL_RTX;
1280
    }
1281
 
1282
  temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1283
                       NULL_RTX, 0, OPTAB_DIRECT);
1284
  if (!temp)
1285
    return NULL_RTX;
1286
 
1287
  /* OP1_HIGH should now be dead.  */
1288
 
1289
  adjust = expand_binop (word_mode, add_optab, adjust, temp,
1290
                         adjust, 0, OPTAB_DIRECT);
1291
 
1292
  if (target && !REG_P (target))
1293
    target = NULL_RTX;
1294
 
1295
  if (umulp)
1296
    product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1297
                            target, 1, OPTAB_DIRECT);
1298
  else
1299
    product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1300
                            target, 1, OPTAB_DIRECT);
1301
 
1302
  if (!product)
1303
    return NULL_RTX;
1304
 
1305
  product_high = operand_subword (product, high, 1, mode);
1306
  adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1307
                         REG_P (product_high) ? product_high : adjust,
1308
                         0, OPTAB_DIRECT);
1309
  emit_move_insn (product_high, adjust);
1310
  return product;
1311
}
1312
 
1313
/* Wrapper around expand_binop which takes an rtx code to specify
1314
   the operation to perform, not an optab pointer.  All other
1315
   arguments are the same.  */
1316
rtx
1317
expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1318
                     rtx op1, rtx target, int unsignedp,
1319
                     enum optab_methods methods)
1320
{
1321
  optab binop = code_to_optab[(int) code];
1322
  gcc_assert (binop);
1323
 
1324
  return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1325
}
1326
 
1327
/* Return whether OP0 and OP1 should be swapped when expanding a commutative
1328
   binop.  Order them according to commutative_operand_precedence and, if
1329
   possible, try to put TARGET or a pseudo first.  */
1330
static bool
1331
swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1332
{
1333
  int op0_prec = commutative_operand_precedence (op0);
1334
  int op1_prec = commutative_operand_precedence (op1);
1335
 
1336
  if (op0_prec < op1_prec)
1337
    return true;
1338
 
1339
  if (op0_prec > op1_prec)
1340
    return false;
1341
 
1342
  /* With equal precedence, both orders are ok, but it is better if the
1343
     first operand is TARGET, or if both TARGET and OP0 are pseudos.  */
1344
  if (target == 0 || REG_P (target))
1345
    return (REG_P (op1) && !REG_P (op0)) || target == op1;
1346
  else
1347
    return rtx_equal_p (op1, target);
1348
}
1349
 
1350
/* Return true if BINOPTAB implements a shift operation.  */
1351
 
1352
static bool
1353
shift_optab_p (optab binoptab)
1354
{
1355
  switch (binoptab->code)
1356
    {
1357
    case ASHIFT:
1358
    case SS_ASHIFT:
1359
    case US_ASHIFT:
1360
    case ASHIFTRT:
1361
    case LSHIFTRT:
1362
    case ROTATE:
1363
    case ROTATERT:
1364
      return true;
1365
 
1366
    default:
1367
      return false;
1368
    }
1369
}
1370
 
1371
/* Return true if BINOPTAB implements a commutative binary operation.  */
1372
 
1373
static bool
1374
commutative_optab_p (optab binoptab)
1375
{
1376
  return (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1377
          || binoptab == smul_widen_optab
1378
          || binoptab == umul_widen_optab
1379
          || binoptab == smul_highpart_optab
1380
          || binoptab == umul_highpart_optab);
1381
}
1382
 
1383
/* X is to be used in mode MODE as an operand to BINOPTAB.  If we're
1384
   optimizing, and if the operand is a constant that costs more than
1385
   1 instruction, force the constant into a register and return that
1386
   register.  Return X otherwise.  UNSIGNEDP says whether X is unsigned.  */
1387
 
1388
static rtx
1389
avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1390
                          rtx x, bool unsignedp)
1391
{
1392
  bool speed = optimize_insn_for_speed_p ();
1393
 
1394
  if (mode != VOIDmode
1395
      && optimize
1396
      && CONSTANT_P (x)
1397
      && rtx_cost (x, binoptab->code, speed) > rtx_cost (x, SET, speed))
1398
    {
1399
      if (CONST_INT_P (x))
1400
        {
1401
          HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1402
          if (intval != INTVAL (x))
1403
            x = GEN_INT (intval);
1404
        }
1405
      else
1406
        x = convert_modes (mode, VOIDmode, x, unsignedp);
1407
      x = force_reg (mode, x);
1408
    }
1409
  return x;
1410
}
1411
 
1412
/* Helper function for expand_binop: handle the case where there
1413
   is an insn that directly implements the indicated operation.
1414
   Returns null if this is not possible.  */
1415
static rtx
1416
expand_binop_directly (enum machine_mode mode, optab binoptab,
1417
                       rtx op0, rtx op1,
1418
                       rtx target, int unsignedp, enum optab_methods methods,
1419
                       rtx last)
1420
{
1421
  int icode = (int) optab_handler (binoptab, mode)->insn_code;
1422
  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1423
  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1424
  enum machine_mode tmp_mode;
1425
  bool commutative_p;
1426
  rtx pat;
1427
  rtx xop0 = op0, xop1 = op1;
1428
  rtx temp;
1429
  rtx swap;
1430
 
1431
  if (target)
1432
    temp = target;
1433
  else
1434
    temp = gen_reg_rtx (mode);
1435
 
1436
  /* If it is a commutative operator and the modes would match
1437
     if we would swap the operands, we can save the conversions.  */
1438
  commutative_p = commutative_optab_p (binoptab);
1439
  if (commutative_p
1440
      && GET_MODE (xop0) != mode0 && GET_MODE (xop1) != mode1
1441
      && GET_MODE (xop0) == mode1 && GET_MODE (xop1) == mode1)
1442
    {
1443
      swap = xop0;
1444
      xop0 = xop1;
1445
      xop1 = swap;
1446
    }
1447
 
1448
  /* If we are optimizing, force expensive constants into a register.  */
1449
  xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
1450
  if (!shift_optab_p (binoptab))
1451
    xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
1452
 
1453
  /* In case the insn wants input operands in modes different from
1454
     those of the actual operands, convert the operands.  It would
1455
     seem that we don't need to convert CONST_INTs, but we do, so
1456
     that they're properly zero-extended, sign-extended or truncated
1457
     for their mode.  */
1458
 
1459
  if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode)
1460
    xop0 = convert_modes (mode0,
1461
                          GET_MODE (xop0) != VOIDmode
1462
                          ? GET_MODE (xop0)
1463
                          : mode,
1464
                          xop0, unsignedp);
1465
 
1466
  if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode)
1467
    xop1 = convert_modes (mode1,
1468
                          GET_MODE (xop1) != VOIDmode
1469
                          ? GET_MODE (xop1)
1470
                          : mode,
1471
                          xop1, unsignedp);
1472
 
1473
  /* If operation is commutative,
1474
     try to make the first operand a register.
1475
     Even better, try to make it the same as the target.
1476
     Also try to make the last operand a constant.  */
1477
  if (commutative_p
1478
      && swap_commutative_operands_with_target (target, xop0, xop1))
1479
    {
1480
      swap = xop1;
1481
      xop1 = xop0;
1482
      xop0 = swap;
1483
    }
1484
 
1485
  /* Now, if insn's predicates don't allow our operands, put them into
1486
     pseudo regs.  */
1487
 
1488
  if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1489
      && mode0 != VOIDmode)
1490
    xop0 = copy_to_mode_reg (mode0, xop0);
1491
 
1492
  if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1493
      && mode1 != VOIDmode)
1494
    xop1 = copy_to_mode_reg (mode1, xop1);
1495
 
1496
  if (binoptab == vec_pack_trunc_optab
1497
      || binoptab == vec_pack_usat_optab
1498
      || binoptab == vec_pack_ssat_optab
1499
      || binoptab == vec_pack_ufix_trunc_optab
1500
      || binoptab == vec_pack_sfix_trunc_optab)
1501
    {
1502
      /* The mode of the result is different then the mode of the
1503
         arguments.  */
1504
      tmp_mode = insn_data[icode].operand[0].mode;
1505
      if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1506
        return 0;
1507
    }
1508
  else
1509
    tmp_mode = mode;
1510
 
1511
  if (!insn_data[icode].operand[0].predicate (temp, tmp_mode))
1512
    temp = gen_reg_rtx (tmp_mode);
1513
 
1514
  pat = GEN_FCN (icode) (temp, xop0, xop1);
1515
  if (pat)
1516
    {
1517
      /* If PAT is composed of more than one insn, try to add an appropriate
1518
         REG_EQUAL note to it.  If we can't because TEMP conflicts with an
1519
         operand, call expand_binop again, this time without a target.  */
1520
      if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1521
          && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1522
        {
1523
          delete_insns_since (last);
1524
          return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1525
                               unsignedp, methods);
1526
        }
1527
 
1528
      emit_insn (pat);
1529
      return temp;
1530
    }
1531
 
1532
  delete_insns_since (last);
1533
  return NULL_RTX;
1534
}
1535
 
1536
/* Generate code to perform an operation specified by BINOPTAB
1537
   on operands OP0 and OP1, with result having machine-mode MODE.
1538
 
1539
   UNSIGNEDP is for the case where we have to widen the operands
1540
   to perform the operation.  It says to use zero-extension.
1541
 
1542
   If TARGET is nonzero, the value
1543
   is generated there, if it is convenient to do so.
1544
   In all cases an rtx is returned for the locus of the value;
1545
   this may or may not be TARGET.  */
1546
 
1547
rtx
1548
expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1549
              rtx target, int unsignedp, enum optab_methods methods)
1550
{
1551
  enum optab_methods next_methods
1552
    = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1553
       ? OPTAB_WIDEN : methods);
1554
  enum mode_class mclass;
1555
  enum machine_mode wider_mode;
1556
  rtx libfunc;
1557
  rtx temp;
1558
  rtx entry_last = get_last_insn ();
1559
  rtx last;
1560
 
1561
  mclass = GET_MODE_CLASS (mode);
1562
 
1563
  /* If subtracting an integer constant, convert this into an addition of
1564
     the negated constant.  */
1565
 
1566
  if (binoptab == sub_optab && CONST_INT_P (op1))
1567
    {
1568
      op1 = negate_rtx (mode, op1);
1569
      binoptab = add_optab;
1570
    }
1571
 
1572
  /* Record where to delete back to if we backtrack.  */
1573
  last = get_last_insn ();
1574
 
1575
  /* If we can do it with a three-operand insn, do so.  */
1576
 
1577
  if (methods != OPTAB_MUST_WIDEN
1578
      && optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
1579
    {
1580
      temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1581
                                    unsignedp, methods, last);
1582
      if (temp)
1583
        return temp;
1584
    }
1585
 
1586
  /* If we were trying to rotate, and that didn't work, try rotating
1587
     the other direction before falling back to shifts and bitwise-or.  */
1588
  if (((binoptab == rotl_optab
1589
        && optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing)
1590
       || (binoptab == rotr_optab
1591
           && optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing))
1592
      && mclass == MODE_INT)
1593
    {
1594
      optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1595
      rtx newop1;
1596
      unsigned int bits = GET_MODE_BITSIZE (mode);
1597
 
1598
      if (CONST_INT_P (op1))
1599
        newop1 = GEN_INT (bits - INTVAL (op1));
1600
      else if (targetm.shift_truncation_mask (mode) == bits - 1)
1601
        newop1 = negate_rtx (GET_MODE (op1), op1);
1602
      else
1603
        newop1 = expand_binop (GET_MODE (op1), sub_optab,
1604
                               GEN_INT (bits), op1,
1605
                               NULL_RTX, unsignedp, OPTAB_DIRECT);
1606
 
1607
      temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1608
                                    target, unsignedp, methods, last);
1609
      if (temp)
1610
        return temp;
1611
    }
1612
 
1613
  /* If this is a multiply, see if we can do a widening operation that
1614
     takes operands of this mode and makes a wider mode.  */
1615
 
1616
  if (binoptab == smul_optab
1617
      && GET_MODE_WIDER_MODE (mode) != VOIDmode
1618
      && ((optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),
1619
                          GET_MODE_WIDER_MODE (mode))->insn_code)
1620
          != CODE_FOR_nothing))
1621
    {
1622
      temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1623
                           unsignedp ? umul_widen_optab : smul_widen_optab,
1624
                           op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1625
 
1626
      if (temp != 0)
1627
        {
1628
          if (GET_MODE_CLASS (mode) == MODE_INT
1629
              && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1630
                                        GET_MODE_BITSIZE (GET_MODE (temp))))
1631
            return gen_lowpart (mode, temp);
1632
          else
1633
            return convert_to_mode (mode, temp, unsignedp);
1634
        }
1635
    }
1636
 
1637
  /* Look for a wider mode of the same class for which we think we
1638
     can open-code the operation.  Check for a widening multiply at the
1639
     wider mode as well.  */
1640
 
1641
  if (CLASS_HAS_WIDER_MODES_P (mclass)
1642
      && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1643
    for (wider_mode = GET_MODE_WIDER_MODE (mode);
1644
         wider_mode != VOIDmode;
1645
         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1646
      {
1647
        if (optab_handler (binoptab, wider_mode)->insn_code != CODE_FOR_nothing
1648
            || (binoptab == smul_optab
1649
                && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1650
                && ((optab_handler ((unsignedp ? umul_widen_optab
1651
                                     : smul_widen_optab),
1652
                                     GET_MODE_WIDER_MODE (wider_mode))->insn_code)
1653
                    != CODE_FOR_nothing)))
1654
          {
1655
            rtx xop0 = op0, xop1 = op1;
1656
            int no_extend = 0;
1657
 
1658
            /* For certain integer operations, we need not actually extend
1659
               the narrow operands, as long as we will truncate
1660
               the results to the same narrowness.  */
1661
 
1662
            if ((binoptab == ior_optab || binoptab == and_optab
1663
                 || binoptab == xor_optab
1664
                 || binoptab == add_optab || binoptab == sub_optab
1665
                 || binoptab == smul_optab || binoptab == ashl_optab)
1666
                && mclass == MODE_INT)
1667
              {
1668
                no_extend = 1;
1669
                xop0 = avoid_expensive_constant (mode, binoptab,
1670
                                                 xop0, unsignedp);
1671
                if (binoptab != ashl_optab)
1672
                  xop1 = avoid_expensive_constant (mode, binoptab,
1673
                                                   xop1, unsignedp);
1674
              }
1675
 
1676
            xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1677
 
1678
            /* The second operand of a shift must always be extended.  */
1679
            xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1680
                                  no_extend && binoptab != ashl_optab);
1681
 
1682
            temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1683
                                 unsignedp, OPTAB_DIRECT);
1684
            if (temp)
1685
              {
1686
                if (mclass != MODE_INT
1687
                    || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1688
                                               GET_MODE_BITSIZE (wider_mode)))
1689
                  {
1690
                    if (target == 0)
1691
                      target = gen_reg_rtx (mode);
1692
                    convert_move (target, temp, 0);
1693
                    return target;
1694
                  }
1695
                else
1696
                  return gen_lowpart (mode, temp);
1697
              }
1698
            else
1699
              delete_insns_since (last);
1700
          }
1701
      }
1702
 
1703
  /* If operation is commutative,
1704
     try to make the first operand a register.
1705
     Even better, try to make it the same as the target.
1706
     Also try to make the last operand a constant.  */
1707
  if (commutative_optab_p (binoptab)
1708
      && swap_commutative_operands_with_target (target, op0, op1))
1709
    {
1710
      temp = op1;
1711
      op1 = op0;
1712
      op0 = temp;
1713
    }
1714
 
1715
  /* These can be done a word at a time.  */
1716
  if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1717
      && mclass == MODE_INT
1718
      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1719
      && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1720
    {
1721
      int i;
1722
      rtx insns;
1723
 
1724
      /* If TARGET is the same as one of the operands, the REG_EQUAL note
1725
         won't be accurate, so use a new target.  */
1726
      if (target == 0 || target == op0 || target == op1)
1727
        target = gen_reg_rtx (mode);
1728
 
1729
      start_sequence ();
1730
 
1731
      /* Do the actual arithmetic.  */
1732
      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1733
        {
1734
          rtx target_piece = operand_subword (target, i, 1, mode);
1735
          rtx x = expand_binop (word_mode, binoptab,
1736
                                operand_subword_force (op0, i, mode),
1737
                                operand_subword_force (op1, i, mode),
1738
                                target_piece, unsignedp, next_methods);
1739
 
1740
          if (x == 0)
1741
            break;
1742
 
1743
          if (target_piece != x)
1744
            emit_move_insn (target_piece, x);
1745
        }
1746
 
1747
      insns = get_insns ();
1748
      end_sequence ();
1749
 
1750
      if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1751
        {
1752
          emit_insn (insns);
1753
          return target;
1754
        }
1755
    }
1756
 
1757
  /* Synthesize double word shifts from single word shifts.  */
1758
  if ((binoptab == lshr_optab || binoptab == ashl_optab
1759
       || binoptab == ashr_optab)
1760
      && mclass == MODE_INT
1761
      && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1762
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1763
      && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing
1764
      && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1765
      && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1766
    {
1767
      unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1768
      enum machine_mode op1_mode;
1769
 
1770
      double_shift_mask = targetm.shift_truncation_mask (mode);
1771
      shift_mask = targetm.shift_truncation_mask (word_mode);
1772
      op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1773
 
1774
      /* Apply the truncation to constant shifts.  */
1775
      if (double_shift_mask > 0 && CONST_INT_P (op1))
1776
        op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1777
 
1778
      if (op1 == CONST0_RTX (op1_mode))
1779
        return op0;
1780
 
1781
      /* Make sure that this is a combination that expand_doubleword_shift
1782
         can handle.  See the comments there for details.  */
1783
      if (double_shift_mask == 0
1784
          || (shift_mask == BITS_PER_WORD - 1
1785
              && double_shift_mask == BITS_PER_WORD * 2 - 1))
1786
        {
1787
          rtx insns;
1788
          rtx into_target, outof_target;
1789
          rtx into_input, outof_input;
1790
          int left_shift, outof_word;
1791
 
1792
          /* If TARGET is the same as one of the operands, the REG_EQUAL note
1793
             won't be accurate, so use a new target.  */
1794
          if (target == 0 || target == op0 || target == op1)
1795
            target = gen_reg_rtx (mode);
1796
 
1797
          start_sequence ();
1798
 
1799
          /* OUTOF_* is the word we are shifting bits away from, and
1800
             INTO_* is the word that we are shifting bits towards, thus
1801
             they differ depending on the direction of the shift and
1802
             WORDS_BIG_ENDIAN.  */
1803
 
1804
          left_shift = binoptab == ashl_optab;
1805
          outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1806
 
1807
          outof_target = operand_subword (target, outof_word, 1, mode);
1808
          into_target = operand_subword (target, 1 - outof_word, 1, mode);
1809
 
1810
          outof_input = operand_subword_force (op0, outof_word, mode);
1811
          into_input = operand_subword_force (op0, 1 - outof_word, mode);
1812
 
1813
          if (expand_doubleword_shift (op1_mode, binoptab,
1814
                                       outof_input, into_input, op1,
1815
                                       outof_target, into_target,
1816
                                       unsignedp, next_methods, shift_mask))
1817
            {
1818
              insns = get_insns ();
1819
              end_sequence ();
1820
 
1821
              emit_insn (insns);
1822
              return target;
1823
            }
1824
          end_sequence ();
1825
        }
1826
    }
1827
 
1828
  /* Synthesize double word rotates from single word shifts.  */
1829
  if ((binoptab == rotl_optab || binoptab == rotr_optab)
1830
      && mclass == MODE_INT
1831
      && CONST_INT_P (op1)
1832
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1833
      && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1834
      && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1835
    {
1836
      rtx insns;
1837
      rtx into_target, outof_target;
1838
      rtx into_input, outof_input;
1839
      rtx inter;
1840
      int shift_count, left_shift, outof_word;
1841
 
1842
      /* If TARGET is the same as one of the operands, the REG_EQUAL note
1843
         won't be accurate, so use a new target. Do this also if target is not
1844
         a REG, first because having a register instead may open optimization
1845
         opportunities, and second because if target and op0 happen to be MEMs
1846
         designating the same location, we would risk clobbering it too early
1847
         in the code sequence we generate below.  */
1848
      if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1849
        target = gen_reg_rtx (mode);
1850
 
1851
      start_sequence ();
1852
 
1853
      shift_count = INTVAL (op1);
1854
 
1855
      /* OUTOF_* is the word we are shifting bits away from, and
1856
         INTO_* is the word that we are shifting bits towards, thus
1857
         they differ depending on the direction of the shift and
1858
         WORDS_BIG_ENDIAN.  */
1859
 
1860
      left_shift = (binoptab == rotl_optab);
1861
      outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1862
 
1863
      outof_target = operand_subword (target, outof_word, 1, mode);
1864
      into_target = operand_subword (target, 1 - outof_word, 1, mode);
1865
 
1866
      outof_input = operand_subword_force (op0, outof_word, mode);
1867
      into_input = operand_subword_force (op0, 1 - outof_word, mode);
1868
 
1869
      if (shift_count == BITS_PER_WORD)
1870
        {
1871
          /* This is just a word swap.  */
1872
          emit_move_insn (outof_target, into_input);
1873
          emit_move_insn (into_target, outof_input);
1874
          inter = const0_rtx;
1875
        }
1876
      else
1877
        {
1878
          rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1879
          rtx first_shift_count, second_shift_count;
1880
          optab reverse_unsigned_shift, unsigned_shift;
1881
 
1882
          reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1883
                                    ? lshr_optab : ashl_optab);
1884
 
1885
          unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1886
                            ? ashl_optab : lshr_optab);
1887
 
1888
          if (shift_count > BITS_PER_WORD)
1889
            {
1890
              first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1891
              second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1892
            }
1893
          else
1894
            {
1895
              first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1896
              second_shift_count = GEN_INT (shift_count);
1897
            }
1898
 
1899
          into_temp1 = expand_binop (word_mode, unsigned_shift,
1900
                                     outof_input, first_shift_count,
1901
                                     NULL_RTX, unsignedp, next_methods);
1902
          into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1903
                                     into_input, second_shift_count,
1904
                                     NULL_RTX, unsignedp, next_methods);
1905
 
1906
          if (into_temp1 != 0 && into_temp2 != 0)
1907
            inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1908
                                  into_target, unsignedp, next_methods);
1909
          else
1910
            inter = 0;
1911
 
1912
          if (inter != 0 && inter != into_target)
1913
            emit_move_insn (into_target, inter);
1914
 
1915
          outof_temp1 = expand_binop (word_mode, unsigned_shift,
1916
                                      into_input, first_shift_count,
1917
                                      NULL_RTX, unsignedp, next_methods);
1918
          outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1919
                                      outof_input, second_shift_count,
1920
                                      NULL_RTX, unsignedp, next_methods);
1921
 
1922
          if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1923
            inter = expand_binop (word_mode, ior_optab,
1924
                                  outof_temp1, outof_temp2,
1925
                                  outof_target, unsignedp, next_methods);
1926
 
1927
          if (inter != 0 && inter != outof_target)
1928
            emit_move_insn (outof_target, inter);
1929
        }
1930
 
1931
      insns = get_insns ();
1932
      end_sequence ();
1933
 
1934
      if (inter != 0)
1935
        {
1936
          emit_insn (insns);
1937
          return target;
1938
        }
1939
    }
1940
 
1941
  /* These can be done a word at a time by propagating carries.  */
1942
  if ((binoptab == add_optab || binoptab == sub_optab)
1943
      && mclass == MODE_INT
1944
      && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1945
      && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1946
    {
1947
      unsigned int i;
1948
      optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1949
      const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1950
      rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1951
      rtx xop0, xop1, xtarget;
1952
 
1953
      /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
1954
         value is one of those, use it.  Otherwise, use 1 since it is the
1955
         one easiest to get.  */
1956
#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1957
      int normalizep = STORE_FLAG_VALUE;
1958
#else
1959
      int normalizep = 1;
1960
#endif
1961
 
1962
      /* Prepare the operands.  */
1963
      xop0 = force_reg (mode, op0);
1964
      xop1 = force_reg (mode, op1);
1965
 
1966
      xtarget = gen_reg_rtx (mode);
1967
 
1968
      if (target == 0 || !REG_P (target))
1969
        target = xtarget;
1970
 
1971
      /* Indicate for flow that the entire target reg is being set.  */
1972
      if (REG_P (target))
1973
        emit_clobber (xtarget);
1974
 
1975
      /* Do the actual arithmetic.  */
1976
      for (i = 0; i < nwords; i++)
1977
        {
1978
          int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1979
          rtx target_piece = operand_subword (xtarget, index, 1, mode);
1980
          rtx op0_piece = operand_subword_force (xop0, index, mode);
1981
          rtx op1_piece = operand_subword_force (xop1, index, mode);
1982
          rtx x;
1983
 
1984
          /* Main add/subtract of the input operands.  */
1985
          x = expand_binop (word_mode, binoptab,
1986
                            op0_piece, op1_piece,
1987
                            target_piece, unsignedp, next_methods);
1988
          if (x == 0)
1989
            break;
1990
 
1991
          if (i + 1 < nwords)
1992
            {
1993
              /* Store carry from main add/subtract.  */
1994
              carry_out = gen_reg_rtx (word_mode);
1995
              carry_out = emit_store_flag_force (carry_out,
1996
                                                 (binoptab == add_optab
1997
                                                  ? LT : GT),
1998
                                                 x, op0_piece,
1999
                                                 word_mode, 1, normalizep);
2000
            }
2001
 
2002
          if (i > 0)
2003
            {
2004
              rtx newx;
2005
 
2006
              /* Add/subtract previous carry to main result.  */
2007
              newx = expand_binop (word_mode,
2008
                                   normalizep == 1 ? binoptab : otheroptab,
2009
                                   x, carry_in,
2010
                                   NULL_RTX, 1, next_methods);
2011
 
2012
              if (i + 1 < nwords)
2013
                {
2014
                  /* Get out carry from adding/subtracting carry in.  */
2015
                  rtx carry_tmp = gen_reg_rtx (word_mode);
2016
                  carry_tmp = emit_store_flag_force (carry_tmp,
2017
                                                     (binoptab == add_optab
2018
                                                      ? LT : GT),
2019
                                                     newx, x,
2020
                                                     word_mode, 1, normalizep);
2021
 
2022
                  /* Logical-ior the two poss. carry together.  */
2023
                  carry_out = expand_binop (word_mode, ior_optab,
2024
                                            carry_out, carry_tmp,
2025
                                            carry_out, 0, next_methods);
2026
                  if (carry_out == 0)
2027
                    break;
2028
                }
2029
              emit_move_insn (target_piece, newx);
2030
            }
2031
          else
2032
            {
2033
              if (x != target_piece)
2034
                emit_move_insn (target_piece, x);
2035
            }
2036
 
2037
          carry_in = carry_out;
2038
        }
2039
 
2040
      if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
2041
        {
2042
          if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing
2043
              || ! rtx_equal_p (target, xtarget))
2044
            {
2045
              rtx temp = emit_move_insn (target, xtarget);
2046
 
2047
              set_unique_reg_note (temp,
2048
                                   REG_EQUAL,
2049
                                   gen_rtx_fmt_ee (binoptab->code, mode,
2050
                                                   copy_rtx (xop0),
2051
                                                   copy_rtx (xop1)));
2052
            }
2053
          else
2054
            target = xtarget;
2055
 
2056
          return target;
2057
        }
2058
 
2059
      else
2060
        delete_insns_since (last);
2061
    }
2062
 
2063
  /* Attempt to synthesize double word multiplies using a sequence of word
2064
     mode multiplications.  We first attempt to generate a sequence using a
2065
     more efficient unsigned widening multiply, and if that fails we then
2066
     try using a signed widening multiply.  */
2067
 
2068
  if (binoptab == smul_optab
2069
      && mclass == MODE_INT
2070
      && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2071
      && optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing
2072
      && optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing)
2073
    {
2074
      rtx product = NULL_RTX;
2075
 
2076
      if (optab_handler (umul_widen_optab, mode)->insn_code
2077
          != CODE_FOR_nothing)
2078
        {
2079
          product = expand_doubleword_mult (mode, op0, op1, target,
2080
                                            true, methods);
2081
          if (!product)
2082
            delete_insns_since (last);
2083
        }
2084
 
2085
      if (product == NULL_RTX
2086
          && optab_handler (smul_widen_optab, mode)->insn_code
2087
             != CODE_FOR_nothing)
2088
        {
2089
          product = expand_doubleword_mult (mode, op0, op1, target,
2090
                                            false, methods);
2091
          if (!product)
2092
            delete_insns_since (last);
2093
        }
2094
 
2095
      if (product != NULL_RTX)
2096
        {
2097
          if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing)
2098
            {
2099
              temp = emit_move_insn (target ? target : product, product);
2100
              set_unique_reg_note (temp,
2101
                                   REG_EQUAL,
2102
                                   gen_rtx_fmt_ee (MULT, mode,
2103
                                                   copy_rtx (op0),
2104
                                                   copy_rtx (op1)));
2105
            }
2106
          return product;
2107
        }
2108
    }
2109
 
2110
  /* It can't be open-coded in this mode.
2111
     Use a library call if one is available and caller says that's ok.  */
2112
 
2113
  libfunc = optab_libfunc (binoptab, mode);
2114
  if (libfunc
2115
      && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2116
    {
2117
      rtx insns;
2118
      rtx op1x = op1;
2119
      enum machine_mode op1_mode = mode;
2120
      rtx value;
2121
 
2122
      start_sequence ();
2123
 
2124
      if (shift_optab_p (binoptab))
2125
        {
2126
          op1_mode = targetm.libgcc_shift_count_mode ();
2127
          /* Specify unsigned here,
2128
             since negative shift counts are meaningless.  */
2129
          op1x = convert_to_mode (op1_mode, op1, 1);
2130
        }
2131
 
2132
      if (GET_MODE (op0) != VOIDmode
2133
          && GET_MODE (op0) != mode)
2134
        op0 = convert_to_mode (mode, op0, unsignedp);
2135
 
2136
      /* Pass 1 for NO_QUEUE so we don't lose any increments
2137
         if the libcall is cse'd or moved.  */
2138
      value = emit_library_call_value (libfunc,
2139
                                       NULL_RTX, LCT_CONST, mode, 2,
2140
                                       op0, mode, op1x, op1_mode);
2141
 
2142
      insns = get_insns ();
2143
      end_sequence ();
2144
 
2145
      target = gen_reg_rtx (mode);
2146
      emit_libcall_block (insns, target, value,
2147
                          gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
2148
 
2149
      return target;
2150
    }
2151
 
2152
  delete_insns_since (last);
2153
 
2154
  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2155
 
2156
  if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2157
         || methods == OPTAB_MUST_WIDEN))
2158
    {
2159
      /* Caller says, don't even try.  */
2160
      delete_insns_since (entry_last);
2161
      return 0;
2162
    }
2163
 
2164
  /* Compute the value of METHODS to pass to recursive calls.
2165
     Don't allow widening to be tried recursively.  */
2166
 
2167
  methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2168
 
2169
  /* Look for a wider mode of the same class for which it appears we can do
2170
     the operation.  */
2171
 
2172
  if (CLASS_HAS_WIDER_MODES_P (mclass))
2173
    {
2174
      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2175
           wider_mode != VOIDmode;
2176
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2177
        {
2178
          if ((optab_handler (binoptab, wider_mode)->insn_code
2179
               != CODE_FOR_nothing)
2180
              || (methods == OPTAB_LIB
2181
                  && optab_libfunc (binoptab, wider_mode)))
2182
            {
2183
              rtx xop0 = op0, xop1 = op1;
2184
              int no_extend = 0;
2185
 
2186
              /* For certain integer operations, we need not actually extend
2187
                 the narrow operands, as long as we will truncate
2188
                 the results to the same narrowness.  */
2189
 
2190
              if ((binoptab == ior_optab || binoptab == and_optab
2191
                   || binoptab == xor_optab
2192
                   || binoptab == add_optab || binoptab == sub_optab
2193
                   || binoptab == smul_optab || binoptab == ashl_optab)
2194
                  && mclass == MODE_INT)
2195
                no_extend = 1;
2196
 
2197
              xop0 = widen_operand (xop0, wider_mode, mode,
2198
                                    unsignedp, no_extend);
2199
 
2200
              /* The second operand of a shift must always be extended.  */
2201
              xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2202
                                    no_extend && binoptab != ashl_optab);
2203
 
2204
              temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2205
                                   unsignedp, methods);
2206
              if (temp)
2207
                {
2208
                  if (mclass != MODE_INT
2209
                      || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2210
                                                 GET_MODE_BITSIZE (wider_mode)))
2211
                    {
2212
                      if (target == 0)
2213
                        target = gen_reg_rtx (mode);
2214
                      convert_move (target, temp, 0);
2215
                      return target;
2216
                    }
2217
                  else
2218
                    return gen_lowpart (mode, temp);
2219
                }
2220
              else
2221
                delete_insns_since (last);
2222
            }
2223
        }
2224
    }
2225
 
2226
  delete_insns_since (entry_last);
2227
  return 0;
2228
}
2229
 
2230
/* Expand a binary operator which has both signed and unsigned forms.
2231
   UOPTAB is the optab for unsigned operations, and SOPTAB is for
2232
   signed operations.
2233
 
2234
   If we widen unsigned operands, we may use a signed wider operation instead
2235
   of an unsigned wider operation, since the result would be the same.  */
2236
 
2237
rtx
2238
sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2239
                   rtx op0, rtx op1, rtx target, int unsignedp,
2240
                   enum optab_methods methods)
2241
{
2242
  rtx temp;
2243
  optab direct_optab = unsignedp ? uoptab : soptab;
2244
  struct optab_d wide_soptab;
2245
 
2246
  /* Do it without widening, if possible.  */
2247
  temp = expand_binop (mode, direct_optab, op0, op1, target,
2248
                       unsignedp, OPTAB_DIRECT);
2249
  if (temp || methods == OPTAB_DIRECT)
2250
    return temp;
2251
 
2252
  /* Try widening to a signed int.  Make a fake signed optab that
2253
     hides any signed insn for direct use.  */
2254
  wide_soptab = *soptab;
2255
  optab_handler (&wide_soptab, mode)->insn_code = CODE_FOR_nothing;
2256
  /* We don't want to generate new hash table entries from this fake
2257
     optab.  */
2258
  wide_soptab.libcall_gen = NULL;
2259
 
2260
  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2261
                       unsignedp, OPTAB_WIDEN);
2262
 
2263
  /* For unsigned operands, try widening to an unsigned int.  */
2264
  if (temp == 0 && unsignedp)
2265
    temp = expand_binop (mode, uoptab, op0, op1, target,
2266
                         unsignedp, OPTAB_WIDEN);
2267
  if (temp || methods == OPTAB_WIDEN)
2268
    return temp;
2269
 
2270
  /* Use the right width libcall if that exists.  */
2271
  temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2272
  if (temp || methods == OPTAB_LIB)
2273
    return temp;
2274
 
2275
  /* Must widen and use a libcall, use either signed or unsigned.  */
2276
  temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2277
                       unsignedp, methods);
2278
  if (temp != 0)
2279
    return temp;
2280
  if (unsignedp)
2281
    return expand_binop (mode, uoptab, op0, op1, target,
2282
                         unsignedp, methods);
2283
  return 0;
2284
}
2285
 
2286
/* Generate code to perform an operation specified by UNOPPTAB
2287
   on operand OP0, with two results to TARG0 and TARG1.
2288
   We assume that the order of the operands for the instruction
2289
   is TARG0, TARG1, OP0.
2290
 
2291
   Either TARG0 or TARG1 may be zero, but what that means is that
2292
   the result is not actually wanted.  We will generate it into
2293
   a dummy pseudo-reg and discard it.  They may not both be zero.
2294
 
2295
   Returns 1 if this operation can be performed; 0 if not.  */
2296
 
2297
int
2298
expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2299
                    int unsignedp)
2300
{
2301
  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2302
  enum mode_class mclass;
2303
  enum machine_mode wider_mode;
2304
  rtx entry_last = get_last_insn ();
2305
  rtx last;
2306
 
2307
  mclass = GET_MODE_CLASS (mode);
2308
 
2309
  if (!targ0)
2310
    targ0 = gen_reg_rtx (mode);
2311
  if (!targ1)
2312
    targ1 = gen_reg_rtx (mode);
2313
 
2314
  /* Record where to go back to if we fail.  */
2315
  last = get_last_insn ();
2316
 
2317
  if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2318
    {
2319
      int icode = (int) optab_handler (unoptab, mode)->insn_code;
2320
      enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2321
      rtx pat;
2322
      rtx xop0 = op0;
2323
 
2324
      if (GET_MODE (xop0) != VOIDmode
2325
          && GET_MODE (xop0) != mode0)
2326
        xop0 = convert_to_mode (mode0, xop0, unsignedp);
2327
 
2328
      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2329
      if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2330
        xop0 = copy_to_mode_reg (mode0, xop0);
2331
 
2332
      /* We could handle this, but we should always be called with a pseudo
2333
         for our targets and all insns should take them as outputs.  */
2334
      gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2335
      gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2336
 
2337
      pat = GEN_FCN (icode) (targ0, targ1, xop0);
2338
      if (pat)
2339
        {
2340
          emit_insn (pat);
2341
          return 1;
2342
        }
2343
      else
2344
        delete_insns_since (last);
2345
    }
2346
 
2347
  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2348
 
2349
  if (CLASS_HAS_WIDER_MODES_P (mclass))
2350
    {
2351
      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2352
           wider_mode != VOIDmode;
2353
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2354
        {
2355
          if (optab_handler (unoptab, wider_mode)->insn_code
2356
              != CODE_FOR_nothing)
2357
            {
2358
              rtx t0 = gen_reg_rtx (wider_mode);
2359
              rtx t1 = gen_reg_rtx (wider_mode);
2360
              rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2361
 
2362
              if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2363
                {
2364
                  convert_move (targ0, t0, unsignedp);
2365
                  convert_move (targ1, t1, unsignedp);
2366
                  return 1;
2367
                }
2368
              else
2369
                delete_insns_since (last);
2370
            }
2371
        }
2372
    }
2373
 
2374
  delete_insns_since (entry_last);
2375
  return 0;
2376
}
2377
 
2378
/* Generate code to perform an operation specified by BINOPTAB
2379
   on operands OP0 and OP1, with two results to TARG1 and TARG2.
2380
   We assume that the order of the operands for the instruction
2381
   is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2382
   [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2383
 
2384
   Either TARG0 or TARG1 may be zero, but what that means is that
2385
   the result is not actually wanted.  We will generate it into
2386
   a dummy pseudo-reg and discard it.  They may not both be zero.
2387
 
2388
   Returns 1 if this operation can be performed; 0 if not.  */
2389
 
2390
int
2391
expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2392
                     int unsignedp)
2393
{
2394
  enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2395
  enum mode_class mclass;
2396
  enum machine_mode wider_mode;
2397
  rtx entry_last = get_last_insn ();
2398
  rtx last;
2399
 
2400
  mclass = GET_MODE_CLASS (mode);
2401
 
2402
  if (!targ0)
2403
    targ0 = gen_reg_rtx (mode);
2404
  if (!targ1)
2405
    targ1 = gen_reg_rtx (mode);
2406
 
2407
  /* Record where to go back to if we fail.  */
2408
  last = get_last_insn ();
2409
 
2410
  if (optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
2411
    {
2412
      int icode = (int) optab_handler (binoptab, mode)->insn_code;
2413
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2414
      enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2415
      rtx pat;
2416
      rtx xop0 = op0, xop1 = op1;
2417
 
2418
      /* If we are optimizing, force expensive constants into a register.  */
2419
      xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
2420
      xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
2421
 
2422
      /* In case the insn wants input operands in modes different from
2423
         those of the actual operands, convert the operands.  It would
2424
         seem that we don't need to convert CONST_INTs, but we do, so
2425
         that they're properly zero-extended, sign-extended or truncated
2426
         for their mode.  */
2427
 
2428
      if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2429
        xop0 = convert_modes (mode0,
2430
                              GET_MODE (op0) != VOIDmode
2431
                              ? GET_MODE (op0)
2432
                              : mode,
2433
                              xop0, unsignedp);
2434
 
2435
      if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2436
        xop1 = convert_modes (mode1,
2437
                              GET_MODE (op1) != VOIDmode
2438
                              ? GET_MODE (op1)
2439
                              : mode,
2440
                              xop1, unsignedp);
2441
 
2442
      /* Now, if insn doesn't accept these operands, put them into pseudos.  */
2443
      if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2444
        xop0 = copy_to_mode_reg (mode0, xop0);
2445
 
2446
      if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2447
        xop1 = copy_to_mode_reg (mode1, xop1);
2448
 
2449
      /* We could handle this, but we should always be called with a pseudo
2450
         for our targets and all insns should take them as outputs.  */
2451
      gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2452
      gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2453
 
2454
      pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2455
      if (pat)
2456
        {
2457
          emit_insn (pat);
2458
          return 1;
2459
        }
2460
      else
2461
        delete_insns_since (last);
2462
    }
2463
 
2464
  /* It can't be done in this mode.  Can we do it in a wider mode?  */
2465
 
2466
  if (CLASS_HAS_WIDER_MODES_P (mclass))
2467
    {
2468
      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2469
           wider_mode != VOIDmode;
2470
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2471
        {
2472
          if (optab_handler (binoptab, wider_mode)->insn_code
2473
              != CODE_FOR_nothing)
2474
            {
2475
              rtx t0 = gen_reg_rtx (wider_mode);
2476
              rtx t1 = gen_reg_rtx (wider_mode);
2477
              rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2478
              rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2479
 
2480
              if (expand_twoval_binop (binoptab, cop0, cop1,
2481
                                       t0, t1, unsignedp))
2482
                {
2483
                  convert_move (targ0, t0, unsignedp);
2484
                  convert_move (targ1, t1, unsignedp);
2485
                  return 1;
2486
                }
2487
              else
2488
                delete_insns_since (last);
2489
            }
2490
        }
2491
    }
2492
 
2493
  delete_insns_since (entry_last);
2494
  return 0;
2495
}
2496
 
2497
/* Expand the two-valued library call indicated by BINOPTAB, but
2498
   preserve only one of the values.  If TARG0 is non-NULL, the first
2499
   value is placed into TARG0; otherwise the second value is placed
2500
   into TARG1.  Exactly one of TARG0 and TARG1 must be non-NULL.  The
2501
   value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2502
   This routine assumes that the value returned by the library call is
2503
   as if the return value was of an integral mode twice as wide as the
2504
   mode of OP0.  Returns 1 if the call was successful.  */
2505
 
2506
bool
2507
expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2508
                             rtx targ0, rtx targ1, enum rtx_code code)
2509
{
2510
  enum machine_mode mode;
2511
  enum machine_mode libval_mode;
2512
  rtx libval;
2513
  rtx insns;
2514
  rtx libfunc;
2515
 
2516
  /* Exactly one of TARG0 or TARG1 should be non-NULL.  */
2517
  gcc_assert (!targ0 != !targ1);
2518
 
2519
  mode = GET_MODE (op0);
2520
  libfunc = optab_libfunc (binoptab, mode);
2521
  if (!libfunc)
2522
    return false;
2523
 
2524
  /* The value returned by the library function will have twice as
2525
     many bits as the nominal MODE.  */
2526
  libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2527
                                        MODE_INT);
2528
  start_sequence ();
2529
  libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2530
                                    libval_mode, 2,
2531
                                    op0, mode,
2532
                                    op1, mode);
2533
  /* Get the part of VAL containing the value that we want.  */
2534
  libval = simplify_gen_subreg (mode, libval, libval_mode,
2535
                                targ0 ? 0 : GET_MODE_SIZE (mode));
2536
  insns = get_insns ();
2537
  end_sequence ();
2538
  /* Move the into the desired location.  */
2539
  emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2540
                      gen_rtx_fmt_ee (code, mode, op0, op1));
2541
 
2542
  return true;
2543
}
2544
 
2545
 
2546
/* Wrapper around expand_unop which takes an rtx code to specify
2547
   the operation to perform, not an optab pointer.  All other
2548
   arguments are the same.  */
2549
rtx
2550
expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2551
                    rtx target, int unsignedp)
2552
{
2553
  optab unop = code_to_optab[(int) code];
2554
  gcc_assert (unop);
2555
 
2556
  return expand_unop (mode, unop, op0, target, unsignedp);
2557
}
2558
 
2559
/* Try calculating
2560
        (clz:narrow x)
2561
   as
2562
        (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).  */
2563
static rtx
2564
widen_clz (enum machine_mode mode, rtx op0, rtx target)
2565
{
2566
  enum mode_class mclass = GET_MODE_CLASS (mode);
2567
  if (CLASS_HAS_WIDER_MODES_P (mclass))
2568
    {
2569
      enum machine_mode wider_mode;
2570
      for (wider_mode = GET_MODE_WIDER_MODE (mode);
2571
           wider_mode != VOIDmode;
2572
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2573
        {
2574
          if (optab_handler (clz_optab, wider_mode)->insn_code
2575
              != CODE_FOR_nothing)
2576
            {
2577
              rtx xop0, temp, last;
2578
 
2579
              last = get_last_insn ();
2580
 
2581
              if (target == 0)
2582
                target = gen_reg_rtx (mode);
2583
              xop0 = widen_operand (op0, wider_mode, mode, true, false);
2584
              temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2585
              if (temp != 0)
2586
                temp = expand_binop (wider_mode, sub_optab, temp,
2587
                                     GEN_INT (GET_MODE_BITSIZE (wider_mode)
2588
                                              - GET_MODE_BITSIZE (mode)),
2589
                                     target, true, OPTAB_DIRECT);
2590
              if (temp == 0)
2591
                delete_insns_since (last);
2592
 
2593
              return temp;
2594
            }
2595
        }
2596
    }
2597
  return 0;
2598
}
2599
 
2600
/* Try calculating clz of a double-word quantity as two clz's of word-sized
2601
   quantities, choosing which based on whether the high word is nonzero.  */
2602
static rtx
2603
expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2604
{
2605
  rtx xop0 = force_reg (mode, op0);
2606
  rtx subhi = gen_highpart (word_mode, xop0);
2607
  rtx sublo = gen_lowpart (word_mode, xop0);
2608
  rtx hi0_label = gen_label_rtx ();
2609
  rtx after_label = gen_label_rtx ();
2610
  rtx seq, temp, result;
2611
 
2612
  /* If we were not given a target, use a word_mode register, not a
2613
     'mode' register.  The result will fit, and nobody is expecting
2614
     anything bigger (the return type of __builtin_clz* is int).  */
2615
  if (!target)
2616
    target = gen_reg_rtx (word_mode);
2617
 
2618
  /* In any case, write to a word_mode scratch in both branches of the
2619
     conditional, so we can ensure there is a single move insn setting
2620
     'target' to tag a REG_EQUAL note on.  */
2621
  result = gen_reg_rtx (word_mode);
2622
 
2623
  start_sequence ();
2624
 
2625
  /* If the high word is not equal to zero,
2626
     then clz of the full value is clz of the high word.  */
2627
  emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2628
                           word_mode, true, hi0_label);
2629
 
2630
  temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2631
  if (!temp)
2632
    goto fail;
2633
 
2634
  if (temp != result)
2635
    convert_move (result, temp, true);
2636
 
2637
  emit_jump_insn (gen_jump (after_label));
2638
  emit_barrier ();
2639
 
2640
  /* Else clz of the full value is clz of the low word plus the number
2641
     of bits in the high word.  */
2642
  emit_label (hi0_label);
2643
 
2644
  temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2645
  if (!temp)
2646
    goto fail;
2647
  temp = expand_binop (word_mode, add_optab, temp,
2648
                       GEN_INT (GET_MODE_BITSIZE (word_mode)),
2649
                       result, true, OPTAB_DIRECT);
2650
  if (!temp)
2651
    goto fail;
2652
  if (temp != result)
2653
    convert_move (result, temp, true);
2654
 
2655
  emit_label (after_label);
2656
  convert_move (target, result, true);
2657
 
2658
  seq = get_insns ();
2659
  end_sequence ();
2660
 
2661
  add_equal_note (seq, target, CLZ, xop0, 0);
2662
  emit_insn (seq);
2663
  return target;
2664
 
2665
 fail:
2666
  end_sequence ();
2667
  return 0;
2668
}
2669
 
2670
/* Try calculating
2671
        (bswap:narrow x)
2672
   as
2673
        (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))).  */
2674
static rtx
2675
widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2676
{
2677
  enum mode_class mclass = GET_MODE_CLASS (mode);
2678
  enum machine_mode wider_mode;
2679
  rtx x, last;
2680
 
2681
  if (!CLASS_HAS_WIDER_MODES_P (mclass))
2682
    return NULL_RTX;
2683
 
2684
  for (wider_mode = GET_MODE_WIDER_MODE (mode);
2685
       wider_mode != VOIDmode;
2686
       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2687
    if (optab_handler (bswap_optab, wider_mode)->insn_code != CODE_FOR_nothing)
2688
      goto found;
2689
  return NULL_RTX;
2690
 
2691
 found:
2692
  last = get_last_insn ();
2693
 
2694
  x = widen_operand (op0, wider_mode, mode, true, true);
2695
  x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2696
 
2697
  if (x != 0)
2698
    x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2699
                      size_int (GET_MODE_BITSIZE (wider_mode)
2700
                                - GET_MODE_BITSIZE (mode)),
2701
                      NULL_RTX, true);
2702
 
2703
  if (x != 0)
2704
    {
2705
      if (target == 0)
2706
        target = gen_reg_rtx (mode);
2707
      emit_move_insn (target, gen_lowpart (mode, x));
2708
    }
2709
  else
2710
    delete_insns_since (last);
2711
 
2712
  return target;
2713
}
2714
 
2715
/* Try calculating bswap as two bswaps of two word-sized operands.  */
2716
 
2717
static rtx
2718
expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2719
{
2720
  rtx t0, t1;
2721
 
2722
  t1 = expand_unop (word_mode, bswap_optab,
2723
                    operand_subword_force (op, 0, mode), NULL_RTX, true);
2724
  t0 = expand_unop (word_mode, bswap_optab,
2725
                    operand_subword_force (op, 1, mode), NULL_RTX, true);
2726
 
2727
  if (target == 0)
2728
    target = gen_reg_rtx (mode);
2729
  if (REG_P (target))
2730
    emit_clobber (target);
2731
  emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2732
  emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2733
 
2734
  return target;
2735
}
2736
 
2737
/* Try calculating (parity x) as (and (popcount x) 1), where
2738
   popcount can also be done in a wider mode.  */
2739
static rtx
2740
expand_parity (enum machine_mode mode, rtx op0, rtx target)
2741
{
2742
  enum mode_class mclass = GET_MODE_CLASS (mode);
2743
  if (CLASS_HAS_WIDER_MODES_P (mclass))
2744
    {
2745
      enum machine_mode wider_mode;
2746
      for (wider_mode = mode; wider_mode != VOIDmode;
2747
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2748
        {
2749
          if (optab_handler (popcount_optab, wider_mode)->insn_code
2750
              != CODE_FOR_nothing)
2751
            {
2752
              rtx xop0, temp, last;
2753
 
2754
              last = get_last_insn ();
2755
 
2756
              if (target == 0)
2757
                target = gen_reg_rtx (mode);
2758
              xop0 = widen_operand (op0, wider_mode, mode, true, false);
2759
              temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2760
                                  true);
2761
              if (temp != 0)
2762
                temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2763
                                     target, true, OPTAB_DIRECT);
2764
              if (temp == 0)
2765
                delete_insns_since (last);
2766
 
2767
              return temp;
2768
            }
2769
        }
2770
    }
2771
  return 0;
2772
}
2773
 
2774
/* Try calculating ctz(x) as K - clz(x & -x) ,
2775
   where K is GET_MODE_BITSIZE(mode) - 1.
2776
 
2777
   Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2778
   don't have to worry about what the hardware does in that case.  (If
2779
   the clz instruction produces the usual value at 0, which is K, the
2780
   result of this code sequence will be -1; expand_ffs, below, relies
2781
   on this.  It might be nice to have it be K instead, for consistency
2782
   with the (very few) processors that provide a ctz with a defined
2783
   value, but that would take one more instruction, and it would be
2784
   less convenient for expand_ffs anyway.  */
2785
 
2786
static rtx
2787
expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2788
{
2789
  rtx seq, temp;
2790
 
2791
  if (optab_handler (clz_optab, mode)->insn_code == CODE_FOR_nothing)
2792
    return 0;
2793
 
2794
  start_sequence ();
2795
 
2796
  temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2797
  if (temp)
2798
    temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2799
                         true, OPTAB_DIRECT);
2800
  if (temp)
2801
    temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2802
  if (temp)
2803
    temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_BITSIZE (mode) - 1),
2804
                         temp, target,
2805
                         true, OPTAB_DIRECT);
2806
  if (temp == 0)
2807
    {
2808
      end_sequence ();
2809
      return 0;
2810
    }
2811
 
2812
  seq = get_insns ();
2813
  end_sequence ();
2814
 
2815
  add_equal_note (seq, temp, CTZ, op0, 0);
2816
  emit_insn (seq);
2817
  return temp;
2818
}
2819
 
2820
 
2821
/* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2822
   else with the sequence used by expand_clz.
2823
 
2824
   The ffs builtin promises to return zero for a zero value and ctz/clz
2825
   may have an undefined value in that case.  If they do not give us a
2826
   convenient value, we have to generate a test and branch.  */
2827
static rtx
2828
expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2829
{
2830
  HOST_WIDE_INT val = 0;
2831
  bool defined_at_zero = false;
2832
  rtx temp, seq;
2833
 
2834
  if (optab_handler (ctz_optab, mode)->insn_code != CODE_FOR_nothing)
2835
    {
2836
      start_sequence ();
2837
 
2838
      temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2839
      if (!temp)
2840
        goto fail;
2841
 
2842
      defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2843
    }
2844
  else if (optab_handler (clz_optab, mode)->insn_code != CODE_FOR_nothing)
2845
    {
2846
      start_sequence ();
2847
      temp = expand_ctz (mode, op0, 0);
2848
      if (!temp)
2849
        goto fail;
2850
 
2851
      if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2852
        {
2853
          defined_at_zero = true;
2854
          val = (GET_MODE_BITSIZE (mode) - 1) - val;
2855
        }
2856
    }
2857
  else
2858
    return 0;
2859
 
2860
  if (defined_at_zero && val == -1)
2861
    /* No correction needed at zero.  */;
2862
  else
2863
    {
2864
      /* We don't try to do anything clever with the situation found
2865
         on some processors (eg Alpha) where ctz(0:mode) ==
2866
         bitsize(mode).  If someone can think of a way to send N to -1
2867
         and leave alone all values in the range 0..N-1 (where N is a
2868
         power of two), cheaper than this test-and-branch, please add it.
2869
 
2870
         The test-and-branch is done after the operation itself, in case
2871
         the operation sets condition codes that can be recycled for this.
2872
         (This is true on i386, for instance.)  */
2873
 
2874
      rtx nonzero_label = gen_label_rtx ();
2875
      emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2876
                               mode, true, nonzero_label);
2877
 
2878
      convert_move (temp, GEN_INT (-1), false);
2879
      emit_label (nonzero_label);
2880
    }
2881
 
2882
  /* temp now has a value in the range -1..bitsize-1.  ffs is supposed
2883
     to produce a value in the range 0..bitsize.  */
2884
  temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2885
                       target, false, OPTAB_DIRECT);
2886
  if (!temp)
2887
    goto fail;
2888
 
2889
  seq = get_insns ();
2890
  end_sequence ();
2891
 
2892
  add_equal_note (seq, temp, FFS, op0, 0);
2893
  emit_insn (seq);
2894
  return temp;
2895
 
2896
 fail:
2897
  end_sequence ();
2898
  return 0;
2899
}
2900
 
2901
/* Extract the OMODE lowpart from VAL, which has IMODE.  Under certain
2902
   conditions, VAL may already be a SUBREG against which we cannot generate
2903
   a further SUBREG.  In this case, we expect forcing the value into a
2904
   register will work around the situation.  */
2905
 
2906
static rtx
2907
lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2908
                           enum machine_mode imode)
2909
{
2910
  rtx ret;
2911
  ret = lowpart_subreg (omode, val, imode);
2912
  if (ret == NULL)
2913
    {
2914
      val = force_reg (imode, val);
2915
      ret = lowpart_subreg (omode, val, imode);
2916
      gcc_assert (ret != NULL);
2917
    }
2918
  return ret;
2919
}
2920
 
2921
/* Expand a floating point absolute value or negation operation via a
2922
   logical operation on the sign bit.  */
2923
 
2924
static rtx
2925
expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2926
                   rtx op0, rtx target)
2927
{
2928
  const struct real_format *fmt;
2929
  int bitpos, word, nwords, i;
2930
  enum machine_mode imode;
2931
  HOST_WIDE_INT hi, lo;
2932
  rtx temp, insns;
2933
 
2934
  /* The format has to have a simple sign bit.  */
2935
  fmt = REAL_MODE_FORMAT (mode);
2936
  if (fmt == NULL)
2937
    return NULL_RTX;
2938
 
2939
  bitpos = fmt->signbit_rw;
2940
  if (bitpos < 0)
2941
    return NULL_RTX;
2942
 
2943
  /* Don't create negative zeros if the format doesn't support them.  */
2944
  if (code == NEG && !fmt->has_signed_zero)
2945
    return NULL_RTX;
2946
 
2947
  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2948
    {
2949
      imode = int_mode_for_mode (mode);
2950
      if (imode == BLKmode)
2951
        return NULL_RTX;
2952
      word = 0;
2953
      nwords = 1;
2954
    }
2955
  else
2956
    {
2957
      imode = word_mode;
2958
 
2959
      if (FLOAT_WORDS_BIG_ENDIAN)
2960
        word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2961
      else
2962
        word = bitpos / BITS_PER_WORD;
2963
      bitpos = bitpos % BITS_PER_WORD;
2964
      nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2965
    }
2966
 
2967
  if (bitpos < HOST_BITS_PER_WIDE_INT)
2968
    {
2969
      hi = 0;
2970
      lo = (HOST_WIDE_INT) 1 << bitpos;
2971
    }
2972
  else
2973
    {
2974
      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2975
      lo = 0;
2976
    }
2977
  if (code == ABS)
2978
    lo = ~lo, hi = ~hi;
2979
 
2980
  if (target == 0 || target == op0)
2981
    target = gen_reg_rtx (mode);
2982
 
2983
  if (nwords > 1)
2984
    {
2985
      start_sequence ();
2986
 
2987
      for (i = 0; i < nwords; ++i)
2988
        {
2989
          rtx targ_piece = operand_subword (target, i, 1, mode);
2990
          rtx op0_piece = operand_subword_force (op0, i, mode);
2991
 
2992
          if (i == word)
2993
            {
2994
              temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2995
                                   op0_piece,
2996
                                   immed_double_const (lo, hi, imode),
2997
                                   targ_piece, 1, OPTAB_LIB_WIDEN);
2998
              if (temp != targ_piece)
2999
                emit_move_insn (targ_piece, temp);
3000
            }
3001
          else
3002
            emit_move_insn (targ_piece, op0_piece);
3003
        }
3004
 
3005
      insns = get_insns ();
3006
      end_sequence ();
3007
 
3008
      emit_insn (insns);
3009
    }
3010
  else
3011
    {
3012
      temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3013
                           gen_lowpart (imode, op0),
3014
                           immed_double_const (lo, hi, imode),
3015
                           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3016
      target = lowpart_subreg_maybe_copy (mode, temp, imode);
3017
 
3018
      set_unique_reg_note (get_last_insn (), REG_EQUAL,
3019
                           gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
3020
    }
3021
 
3022
  return target;
3023
}
3024
 
3025
/* As expand_unop, but will fail rather than attempt the operation in a
3026
   different mode or with a libcall.  */
3027
static rtx
3028
expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
3029
             int unsignedp)
3030
{
3031
  if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
3032
    {
3033
      int icode = (int) optab_handler (unoptab, mode)->insn_code;
3034
      enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3035
      rtx xop0 = op0;
3036
      rtx last = get_last_insn ();
3037
      rtx pat, temp;
3038
 
3039
      if (target)
3040
        temp = target;
3041
      else
3042
        temp = gen_reg_rtx (mode);
3043
 
3044
      if (GET_MODE (xop0) != VOIDmode
3045
          && GET_MODE (xop0) != mode0)
3046
        xop0 = convert_to_mode (mode0, xop0, unsignedp);
3047
 
3048
      /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
3049
 
3050
      if (!insn_data[icode].operand[1].predicate (xop0, mode0))
3051
        xop0 = copy_to_mode_reg (mode0, xop0);
3052
 
3053
      if (!insn_data[icode].operand[0].predicate (temp, mode))
3054
        temp = gen_reg_rtx (mode);
3055
 
3056
      pat = GEN_FCN (icode) (temp, xop0);
3057
      if (pat)
3058
        {
3059
          if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3060
              && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
3061
            {
3062
              delete_insns_since (last);
3063
              return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3064
            }
3065
 
3066
          emit_insn (pat);
3067
 
3068
          return temp;
3069
        }
3070
      else
3071
        delete_insns_since (last);
3072
    }
3073
  return 0;
3074
}
3075
 
3076
/* Generate code to perform an operation specified by UNOPTAB
3077
   on operand OP0, with result having machine-mode MODE.
3078
 
3079
   UNSIGNEDP is for the case where we have to widen the operands
3080
   to perform the operation.  It says to use zero-extension.
3081
 
3082
   If TARGET is nonzero, the value
3083
   is generated there, if it is convenient to do so.
3084
   In all cases an rtx is returned for the locus of the value;
3085
   this may or may not be TARGET.  */
3086
 
3087
rtx
3088
expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
3089
             int unsignedp)
3090
{
3091
  enum mode_class mclass = GET_MODE_CLASS (mode);
3092
  enum machine_mode wider_mode;
3093
  rtx temp;
3094
  rtx libfunc;
3095
 
3096
  temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3097
  if (temp)
3098
    return temp;
3099
 
3100
  /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
3101
 
3102
  /* Widening (or narrowing) clz needs special treatment.  */
3103
  if (unoptab == clz_optab)
3104
    {
3105
      temp = widen_clz (mode, op0, target);
3106
      if (temp)
3107
        return temp;
3108
 
3109
      if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3110
          && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3111
        {
3112
          temp = expand_doubleword_clz (mode, op0, target);
3113
          if (temp)
3114
            return temp;
3115
        }
3116
 
3117
        goto try_libcall;
3118
    }
3119
 
3120
  /* Widening (or narrowing) bswap needs special treatment.  */
3121
  if (unoptab == bswap_optab)
3122
    {
3123
      temp = widen_bswap (mode, op0, target);
3124
      if (temp)
3125
        return temp;
3126
 
3127
      if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3128
          && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3129
        {
3130
          temp = expand_doubleword_bswap (mode, op0, target);
3131
          if (temp)
3132
            return temp;
3133
        }
3134
 
3135
      goto try_libcall;
3136
    }
3137
 
3138
  if (CLASS_HAS_WIDER_MODES_P (mclass))
3139
    for (wider_mode = GET_MODE_WIDER_MODE (mode);
3140
         wider_mode != VOIDmode;
3141
         wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3142
      {
3143
        if (optab_handler (unoptab, wider_mode)->insn_code != CODE_FOR_nothing)
3144
          {
3145
            rtx xop0 = op0;
3146
            rtx last = get_last_insn ();
3147
 
3148
            /* For certain operations, we need not actually extend
3149
               the narrow operand, as long as we will truncate the
3150
               results to the same narrowness.  */
3151
 
3152
            xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3153
                                  (unoptab == neg_optab
3154
                                   || unoptab == one_cmpl_optab)
3155
                                  && mclass == MODE_INT);
3156
 
3157
            temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3158
                                unsignedp);
3159
 
3160
            if (temp)
3161
              {
3162
                if (mclass != MODE_INT
3163
                    || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
3164
                                               GET_MODE_BITSIZE (wider_mode)))
3165
                  {
3166
                    if (target == 0)
3167
                      target = gen_reg_rtx (mode);
3168
                    convert_move (target, temp, 0);
3169
                    return target;
3170
                  }
3171
                else
3172
                  return gen_lowpart (mode, temp);
3173
              }
3174
            else
3175
              delete_insns_since (last);
3176
          }
3177
      }
3178
 
3179
  /* These can be done a word at a time.  */
3180
  if (unoptab == one_cmpl_optab
3181
      && mclass == MODE_INT
3182
      && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3183
      && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3184
    {
3185
      int i;
3186
      rtx insns;
3187
 
3188
      if (target == 0 || target == op0)
3189
        target = gen_reg_rtx (mode);
3190
 
3191
      start_sequence ();
3192
 
3193
      /* Do the actual arithmetic.  */
3194
      for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3195
        {
3196
          rtx target_piece = operand_subword (target, i, 1, mode);
3197
          rtx x = expand_unop (word_mode, unoptab,
3198
                               operand_subword_force (op0, i, mode),
3199
                               target_piece, unsignedp);
3200
 
3201
          if (target_piece != x)
3202
            emit_move_insn (target_piece, x);
3203
        }
3204
 
3205
      insns = get_insns ();
3206
      end_sequence ();
3207
 
3208
      emit_insn (insns);
3209
      return target;
3210
    }
3211
 
3212
  if (unoptab->code == NEG)
3213
    {
3214
      /* Try negating floating point values by flipping the sign bit.  */
3215
      if (SCALAR_FLOAT_MODE_P (mode))
3216
        {
3217
          temp = expand_absneg_bit (NEG, mode, op0, target);
3218
          if (temp)
3219
            return temp;
3220
        }
3221
 
3222
      /* If there is no negation pattern, and we have no negative zero,
3223
         try subtracting from zero.  */
3224
      if (!HONOR_SIGNED_ZEROS (mode))
3225
        {
3226
          temp = expand_binop (mode, (unoptab == negv_optab
3227
                                      ? subv_optab : sub_optab),
3228
                               CONST0_RTX (mode), op0, target,
3229
                               unsignedp, OPTAB_DIRECT);
3230
          if (temp)
3231
            return temp;
3232
        }
3233
    }
3234
 
3235
  /* Try calculating parity (x) as popcount (x) % 2.  */
3236
  if (unoptab == parity_optab)
3237
    {
3238
      temp = expand_parity (mode, op0, target);
3239
      if (temp)
3240
        return temp;
3241
    }
3242
 
3243
  /* Try implementing ffs (x) in terms of clz (x).  */
3244
  if (unoptab == ffs_optab)
3245
    {
3246
      temp = expand_ffs (mode, op0, target);
3247
      if (temp)
3248
        return temp;
3249
    }
3250
 
3251
  /* Try implementing ctz (x) in terms of clz (x).  */
3252
  if (unoptab == ctz_optab)
3253
    {
3254
      temp = expand_ctz (mode, op0, target);
3255
      if (temp)
3256
        return temp;
3257
    }
3258
 
3259
 try_libcall:
3260
  /* Now try a library call in this mode.  */
3261
  libfunc = optab_libfunc (unoptab, mode);
3262
  if (libfunc)
3263
    {
3264
      rtx insns;
3265
      rtx value;
3266
      rtx eq_value;
3267
      enum machine_mode outmode = mode;
3268
 
3269
      /* All of these functions return small values.  Thus we choose to
3270
         have them return something that isn't a double-word.  */
3271
      if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3272
          || unoptab == popcount_optab || unoptab == parity_optab)
3273
        outmode
3274
          = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3275
                                          optab_libfunc (unoptab, mode)));
3276
 
3277
      start_sequence ();
3278
 
3279
      /* Pass 1 for NO_QUEUE so we don't lose any increments
3280
         if the libcall is cse'd or moved.  */
3281
      value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3282
                                       1, op0, mode);
3283
      insns = get_insns ();
3284
      end_sequence ();
3285
 
3286
      target = gen_reg_rtx (outmode);
3287
      eq_value = gen_rtx_fmt_e (unoptab->code, mode, op0);
3288
      if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
3289
        eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3290
      else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
3291
        eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
3292
      emit_libcall_block (insns, target, value, eq_value);
3293
 
3294
      return target;
3295
    }
3296
 
3297
  /* It can't be done in this mode.  Can we do it in a wider mode?  */
3298
 
3299
  if (CLASS_HAS_WIDER_MODES_P (mclass))
3300
    {
3301
      for (wider_mode = GET_MODE_WIDER_MODE (mode);
3302
           wider_mode != VOIDmode;
3303
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3304
        {
3305
          if ((optab_handler (unoptab, wider_mode)->insn_code
3306
               != CODE_FOR_nothing)
3307
              || optab_libfunc (unoptab, wider_mode))
3308
            {
3309
              rtx xop0 = op0;
3310
              rtx last = get_last_insn ();
3311
 
3312
              /* For certain operations, we need not actually extend
3313
                 the narrow operand, as long as we will truncate the
3314
                 results to the same narrowness.  */
3315
 
3316
              xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3317
                                    (unoptab == neg_optab
3318
                                     || unoptab == one_cmpl_optab)
3319
                                    && mclass == MODE_INT);
3320
 
3321
              temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3322
                                  unsignedp);
3323
 
3324
              /* If we are generating clz using wider mode, adjust the
3325
                 result.  */
3326
              if (unoptab == clz_optab && temp != 0)
3327
                temp = expand_binop (wider_mode, sub_optab, temp,
3328
                                     GEN_INT (GET_MODE_BITSIZE (wider_mode)
3329
                                              - GET_MODE_BITSIZE (mode)),
3330
                                     target, true, OPTAB_DIRECT);
3331
 
3332
              if (temp)
3333
                {
3334
                  if (mclass != MODE_INT)
3335
                    {
3336
                      if (target == 0)
3337
                        target = gen_reg_rtx (mode);
3338
                      convert_move (target, temp, 0);
3339
                      return target;
3340
                    }
3341
                  else
3342
                    return gen_lowpart (mode, temp);
3343
                }
3344
              else
3345
                delete_insns_since (last);
3346
            }
3347
        }
3348
    }
3349
 
3350
  /* One final attempt at implementing negation via subtraction,
3351
     this time allowing widening of the operand.  */
3352
  if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
3353
    {
3354
      rtx temp;
3355
      temp = expand_binop (mode,
3356
                           unoptab == negv_optab ? subv_optab : sub_optab,
3357
                           CONST0_RTX (mode), op0,
3358
                           target, unsignedp, OPTAB_LIB_WIDEN);
3359
      if (temp)
3360
        return temp;
3361
    }
3362
 
3363
  return 0;
3364
}
3365
 
3366
/* Emit code to compute the absolute value of OP0, with result to
3367
   TARGET if convenient.  (TARGET may be 0.)  The return value says
3368
   where the result actually is to be found.
3369
 
3370
   MODE is the mode of the operand; the mode of the result is
3371
   different but can be deduced from MODE.
3372
 
3373
 */
3374
 
3375
rtx
3376
expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3377
                   int result_unsignedp)
3378
{
3379
  rtx temp;
3380
 
3381
  if (! flag_trapv)
3382
    result_unsignedp = 1;
3383
 
3384
  /* First try to do it with a special abs instruction.  */
3385
  temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3386
                      op0, target, 0);
3387
  if (temp != 0)
3388
    return temp;
3389
 
3390
  /* For floating point modes, try clearing the sign bit.  */
3391
  if (SCALAR_FLOAT_MODE_P (mode))
3392
    {
3393
      temp = expand_absneg_bit (ABS, mode, op0, target);
3394
      if (temp)
3395
        return temp;
3396
    }
3397
 
3398
  /* If we have a MAX insn, we can do this as MAX (x, -x).  */
3399
  if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing
3400
      && !HONOR_SIGNED_ZEROS (mode))
3401
    {
3402
      rtx last = get_last_insn ();
3403
 
3404
      temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3405
      if (temp != 0)
3406
        temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3407
                             OPTAB_WIDEN);
3408
 
3409
      if (temp != 0)
3410
        return temp;
3411
 
3412
      delete_insns_since (last);
3413
    }
3414
 
3415
  /* If this machine has expensive jumps, we can do integer absolute
3416
     value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3417
     where W is the width of MODE.  */
3418
 
3419
  if (GET_MODE_CLASS (mode) == MODE_INT
3420
      && BRANCH_COST (optimize_insn_for_speed_p (),
3421
                      false) >= 2)
3422
    {
3423
      rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3424
                                   size_int (GET_MODE_BITSIZE (mode) - 1),
3425
                                   NULL_RTX, 0);
3426
 
3427
      temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3428
                           OPTAB_LIB_WIDEN);
3429
      if (temp != 0)
3430
        temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3431
                             temp, extended, target, 0, OPTAB_LIB_WIDEN);
3432
 
3433
      if (temp != 0)
3434
        return temp;
3435
    }
3436
 
3437
  return NULL_RTX;
3438
}
3439
 
3440
rtx
3441
expand_abs (enum machine_mode mode, rtx op0, rtx target,
3442
            int result_unsignedp, int safe)
3443
{
3444
  rtx temp, op1;
3445
 
3446
  if (! flag_trapv)
3447
    result_unsignedp = 1;
3448
 
3449
  temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3450
  if (temp != 0)
3451
    return temp;
3452
 
3453
  /* If that does not win, use conditional jump and negate.  */
3454
 
3455
  /* It is safe to use the target if it is the same
3456
     as the source if this is also a pseudo register */
3457
  if (op0 == target && REG_P (op0)
3458
      && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3459
    safe = 1;
3460
 
3461
  op1 = gen_label_rtx ();
3462
  if (target == 0 || ! safe
3463
      || GET_MODE (target) != mode
3464
      || (MEM_P (target) && MEM_VOLATILE_P (target))
3465
      || (REG_P (target)
3466
          && REGNO (target) < FIRST_PSEUDO_REGISTER))
3467
    target = gen_reg_rtx (mode);
3468
 
3469
  emit_move_insn (target, op0);
3470
  NO_DEFER_POP;
3471
 
3472
  do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3473
                           NULL_RTX, NULL_RTX, op1, -1);
3474
 
3475
  op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3476
                     target, target, 0);
3477
  if (op0 != target)
3478
    emit_move_insn (target, op0);
3479
  emit_label (op1);
3480
  OK_DEFER_POP;
3481
  return target;
3482
}
3483
 
3484
/* Emit code to compute the one's complement absolute value of OP0
3485
   (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3486
   (TARGET may be NULL_RTX.)  The return value says where the result
3487
   actually is to be found.
3488
 
3489
   MODE is the mode of the operand; the mode of the result is
3490
   different but can be deduced from MODE.  */
3491
 
3492
rtx
3493
expand_one_cmpl_abs_nojump (enum machine_mode mode, rtx op0, rtx target)
3494
{
3495
  rtx temp;
3496
 
3497
  /* Not applicable for floating point modes.  */
3498
  if (FLOAT_MODE_P (mode))
3499
    return NULL_RTX;
3500
 
3501
  /* If we have a MAX insn, we can do this as MAX (x, ~x).  */
3502
  if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing)
3503
    {
3504
      rtx last = get_last_insn ();
3505
 
3506
      temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3507
      if (temp != 0)
3508
        temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3509
                             OPTAB_WIDEN);
3510
 
3511
      if (temp != 0)
3512
        return temp;
3513
 
3514
      delete_insns_since (last);
3515
    }
3516
 
3517
  /* If this machine has expensive jumps, we can do one's complement
3518
     absolute value of X as (((signed) x >> (W-1)) ^ x).  */
3519
 
3520
  if (GET_MODE_CLASS (mode) == MODE_INT
3521
      && BRANCH_COST (optimize_insn_for_speed_p (),
3522
                     false) >= 2)
3523
    {
3524
      rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3525
                                   size_int (GET_MODE_BITSIZE (mode) - 1),
3526
                                   NULL_RTX, 0);
3527
 
3528
      temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3529
                           OPTAB_LIB_WIDEN);
3530
 
3531
      if (temp != 0)
3532
        return temp;
3533
    }
3534
 
3535
  return NULL_RTX;
3536
}
3537
 
3538
/* A subroutine of expand_copysign, perform the copysign operation using the
3539
   abs and neg primitives advertised to exist on the target.  The assumption
3540
   is that we have a split register file, and leaving op0 in fp registers,
3541
   and not playing with subregs so much, will help the register allocator.  */
3542
 
3543
static rtx
3544
expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3545
                        int bitpos, bool op0_is_abs)
3546
{
3547
  enum machine_mode imode;
3548
  int icode;
3549
  rtx sign, label;
3550
 
3551
  if (target == op1)
3552
    target = NULL_RTX;
3553
 
3554
  /* Check if the back end provides an insn that handles signbit for the
3555
     argument's mode. */
3556
  icode = (int) signbit_optab->handlers [(int) mode].insn_code;
3557
  if (icode != CODE_FOR_nothing)
3558
    {
3559
      imode = insn_data[icode].operand[0].mode;
3560
      sign = gen_reg_rtx (imode);
3561
      emit_unop_insn (icode, sign, op1, UNKNOWN);
3562
    }
3563
  else
3564
    {
3565
      HOST_WIDE_INT hi, lo;
3566
 
3567
      if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3568
        {
3569
          imode = int_mode_for_mode (mode);
3570
          if (imode == BLKmode)
3571
            return NULL_RTX;
3572
          op1 = gen_lowpart (imode, op1);
3573
        }
3574
      else
3575
        {
3576
          int word;
3577
 
3578
          imode = word_mode;
3579
          if (FLOAT_WORDS_BIG_ENDIAN)
3580
            word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3581
          else
3582
            word = bitpos / BITS_PER_WORD;
3583
          bitpos = bitpos % BITS_PER_WORD;
3584
          op1 = operand_subword_force (op1, word, mode);
3585
        }
3586
 
3587
      if (bitpos < HOST_BITS_PER_WIDE_INT)
3588
        {
3589
          hi = 0;
3590
          lo = (HOST_WIDE_INT) 1 << bitpos;
3591
        }
3592
      else
3593
        {
3594
          hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3595
          lo = 0;
3596
        }
3597
 
3598
      sign = gen_reg_rtx (imode);
3599
      sign = expand_binop (imode, and_optab, op1,
3600
                           immed_double_const (lo, hi, imode),
3601
                           NULL_RTX, 1, OPTAB_LIB_WIDEN);
3602
    }
3603
 
3604
  if (!op0_is_abs)
3605
    {
3606
      op0 = expand_unop (mode, abs_optab, op0, target, 0);
3607
      if (op0 == NULL)
3608
        return NULL_RTX;
3609
      target = op0;
3610
    }
3611
  else
3612
    {
3613
      if (target == NULL_RTX)
3614
        target = copy_to_reg (op0);
3615
      else
3616
        emit_move_insn (target, op0);
3617
    }
3618
 
3619
  label = gen_label_rtx ();
3620
  emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3621
 
3622
  if (GET_CODE (op0) == CONST_DOUBLE)
3623
    op0 = simplify_unary_operation (NEG, mode, op0, mode);
3624
  else
3625
    op0 = expand_unop (mode, neg_optab, op0, target, 0);
3626
  if (op0 != target)
3627
    emit_move_insn (target, op0);
3628
 
3629
  emit_label (label);
3630
 
3631
  return target;
3632
}
3633
 
3634
 
3635
/* A subroutine of expand_copysign, perform the entire copysign operation
3636
   with integer bitmasks.  BITPOS is the position of the sign bit; OP0_IS_ABS
3637
   is true if op0 is known to have its sign bit clear.  */
3638
 
3639
static rtx
3640
expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3641
                     int bitpos, bool op0_is_abs)
3642
{
3643
  enum machine_mode imode;
3644
  HOST_WIDE_INT hi, lo;
3645
  int word, nwords, i;
3646
  rtx temp, insns;
3647
 
3648
  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3649
    {
3650
      imode = int_mode_for_mode (mode);
3651
      if (imode == BLKmode)
3652
        return NULL_RTX;
3653
      word = 0;
3654
      nwords = 1;
3655
    }
3656
  else
3657
    {
3658
      imode = word_mode;
3659
 
3660
      if (FLOAT_WORDS_BIG_ENDIAN)
3661
        word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3662
      else
3663
        word = bitpos / BITS_PER_WORD;
3664
      bitpos = bitpos % BITS_PER_WORD;
3665
      nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3666
    }
3667
 
3668
  if (bitpos < HOST_BITS_PER_WIDE_INT)
3669
    {
3670
      hi = 0;
3671
      lo = (HOST_WIDE_INT) 1 << bitpos;
3672
    }
3673
  else
3674
    {
3675
      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3676
      lo = 0;
3677
    }
3678
 
3679
  if (target == 0 || target == op0 || target == op1)
3680
    target = gen_reg_rtx (mode);
3681
 
3682
  if (nwords > 1)
3683
    {
3684
      start_sequence ();
3685
 
3686
      for (i = 0; i < nwords; ++i)
3687
        {
3688
          rtx targ_piece = operand_subword (target, i, 1, mode);
3689
          rtx op0_piece = operand_subword_force (op0, i, mode);
3690
 
3691
          if (i == word)
3692
            {
3693
              if (!op0_is_abs)
3694
                op0_piece = expand_binop (imode, and_optab, op0_piece,
3695
                                          immed_double_const (~lo, ~hi, imode),
3696
                                          NULL_RTX, 1, OPTAB_LIB_WIDEN);
3697
 
3698
              op1 = expand_binop (imode, and_optab,
3699
                                  operand_subword_force (op1, i, mode),
3700
                                  immed_double_const (lo, hi, imode),
3701
                                  NULL_RTX, 1, OPTAB_LIB_WIDEN);
3702
 
3703
              temp = expand_binop (imode, ior_optab, op0_piece, op1,
3704
                                   targ_piece, 1, OPTAB_LIB_WIDEN);
3705
              if (temp != targ_piece)
3706
                emit_move_insn (targ_piece, temp);
3707
            }
3708
          else
3709
            emit_move_insn (targ_piece, op0_piece);
3710
        }
3711
 
3712
      insns = get_insns ();
3713
      end_sequence ();
3714
 
3715
      emit_insn (insns);
3716
    }
3717
  else
3718
    {
3719
      op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3720
                          immed_double_const (lo, hi, imode),
3721
                          NULL_RTX, 1, OPTAB_LIB_WIDEN);
3722
 
3723
      op0 = gen_lowpart (imode, op0);
3724
      if (!op0_is_abs)
3725
        op0 = expand_binop (imode, and_optab, op0,
3726
                            immed_double_const (~lo, ~hi, imode),
3727
                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
3728
 
3729
      temp = expand_binop (imode, ior_optab, op0, op1,
3730
                           gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3731
      target = lowpart_subreg_maybe_copy (mode, temp, imode);
3732
    }
3733
 
3734
  return target;
3735
}
3736
 
3737
/* Expand the C99 copysign operation.  OP0 and OP1 must be the same
3738
   scalar floating point mode.  Return NULL if we do not know how to
3739
   expand the operation inline.  */
3740
 
3741
rtx
3742
expand_copysign (rtx op0, rtx op1, rtx target)
3743
{
3744
  enum machine_mode mode = GET_MODE (op0);
3745
  const struct real_format *fmt;
3746
  bool op0_is_abs;
3747
  rtx temp;
3748
 
3749
  gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3750
  gcc_assert (GET_MODE (op1) == mode);
3751
 
3752
  /* First try to do it with a special instruction.  */
3753
  temp = expand_binop (mode, copysign_optab, op0, op1,
3754
                       target, 0, OPTAB_DIRECT);
3755
  if (temp)
3756
    return temp;
3757
 
3758
  fmt = REAL_MODE_FORMAT (mode);
3759
  if (fmt == NULL || !fmt->has_signed_zero)
3760
    return NULL_RTX;
3761
 
3762
  op0_is_abs = false;
3763
  if (GET_CODE (op0) == CONST_DOUBLE)
3764
    {
3765
      if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3766
        op0 = simplify_unary_operation (ABS, mode, op0, mode);
3767
      op0_is_abs = true;
3768
    }
3769
 
3770
  if (fmt->signbit_ro >= 0
3771
      && (GET_CODE (op0) == CONST_DOUBLE
3772
          || (optab_handler (neg_optab, mode)->insn_code != CODE_FOR_nothing
3773
              && optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing)))
3774
    {
3775
      temp = expand_copysign_absneg (mode, op0, op1, target,
3776
                                     fmt->signbit_ro, op0_is_abs);
3777
      if (temp)
3778
        return temp;
3779
    }
3780
 
3781
  if (fmt->signbit_rw < 0)
3782
    return NULL_RTX;
3783
  return expand_copysign_bit (mode, op0, op1, target,
3784
                              fmt->signbit_rw, op0_is_abs);
3785
}
3786
 
3787
/* Generate an instruction whose insn-code is INSN_CODE,
3788
   with two operands: an output TARGET and an input OP0.
3789
   TARGET *must* be nonzero, and the output is always stored there.
3790
   CODE is an rtx code such that (CODE OP0) is an rtx that describes
3791
   the value that is stored into TARGET.
3792
 
3793
   Return false if expansion failed.  */
3794
 
3795
bool
3796
maybe_emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3797
{
3798
  rtx temp;
3799
  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3800
  rtx pat;
3801
  rtx last = get_last_insn ();
3802
 
3803
  temp = target;
3804
 
3805
  /* Now, if insn does not accept our operands, put them into pseudos.  */
3806
 
3807
  if (!insn_data[icode].operand[1].predicate (op0, mode0))
3808
    op0 = copy_to_mode_reg (mode0, op0);
3809
 
3810
  if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3811
    temp = gen_reg_rtx (GET_MODE (temp));
3812
 
3813
  pat = GEN_FCN (icode) (temp, op0);
3814
  if (!pat)
3815
    {
3816
      delete_insns_since (last);
3817
      return false;
3818
    }
3819
 
3820
  if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3821
    add_equal_note (pat, temp, code, op0, NULL_RTX);
3822
 
3823
  emit_insn (pat);
3824
 
3825
  if (temp != target)
3826
    emit_move_insn (target, temp);
3827
  return true;
3828
}
3829
/* Generate an instruction whose insn-code is INSN_CODE,
3830
   with two operands: an output TARGET and an input OP0.
3831
   TARGET *must* be nonzero, and the output is always stored there.
3832
   CODE is an rtx code such that (CODE OP0) is an rtx that describes
3833
   the value that is stored into TARGET.  */
3834
 
3835
void
3836
emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3837
{
3838
  bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3839
  gcc_assert (ok);
3840
}
3841
 
3842
struct no_conflict_data
3843
{
3844
  rtx target, first, insn;
3845
  bool must_stay;
3846
};
3847
 
3848
/* Called via note_stores by emit_libcall_block.  Set P->must_stay if
3849
   the currently examined clobber / store has to stay in the list of
3850
   insns that constitute the actual libcall block.  */
3851
static void
3852
no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3853
{
3854
  struct no_conflict_data *p= (struct no_conflict_data *) p0;
3855
 
3856
  /* If this inns directly contributes to setting the target, it must stay.  */
3857
  if (reg_overlap_mentioned_p (p->target, dest))
3858
    p->must_stay = true;
3859
  /* If we haven't committed to keeping any other insns in the list yet,
3860
     there is nothing more to check.  */
3861
  else if (p->insn == p->first)
3862
    return;
3863
  /* If this insn sets / clobbers a register that feeds one of the insns
3864
     already in the list, this insn has to stay too.  */
3865
  else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3866
           || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3867
           || reg_used_between_p (dest, p->first, p->insn)
3868
           /* Likewise if this insn depends on a register set by a previous
3869
              insn in the list, or if it sets a result (presumably a hard
3870
              register) that is set or clobbered by a previous insn.
3871
              N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3872
              SET_DEST perform the former check on the address, and the latter
3873
              check on the MEM.  */
3874
           || (GET_CODE (set) == SET
3875
               && (modified_in_p (SET_SRC (set), p->first)
3876
                   || modified_in_p (SET_DEST (set), p->first)
3877
                   || modified_between_p (SET_SRC (set), p->first, p->insn)
3878
                   || modified_between_p (SET_DEST (set), p->first, p->insn))))
3879
    p->must_stay = true;
3880
}
3881
 
3882
 
3883
/* Emit code to make a call to a constant function or a library call.
3884
 
3885
   INSNS is a list containing all insns emitted in the call.
3886
   These insns leave the result in RESULT.  Our block is to copy RESULT
3887
   to TARGET, which is logically equivalent to EQUIV.
3888
 
3889
   We first emit any insns that set a pseudo on the assumption that these are
3890
   loading constants into registers; doing so allows them to be safely cse'ed
3891
   between blocks.  Then we emit all the other insns in the block, followed by
3892
   an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
3893
   note with an operand of EQUIV.  */
3894
 
3895
void
3896
emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3897
{
3898
  rtx final_dest = target;
3899
  rtx next, last, insn;
3900
 
3901
  /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3902
     into a MEM later.  Protect the libcall block from this change.  */
3903
  if (! REG_P (target) || REG_USERVAR_P (target))
3904
    target = gen_reg_rtx (GET_MODE (target));
3905
 
3906
  /* If we're using non-call exceptions, a libcall corresponding to an
3907
     operation that may trap may also trap.  */
3908
  /* ??? See the comment in front of make_reg_eh_region_note.  */
3909
  if (flag_non_call_exceptions && may_trap_p (equiv))
3910
    {
3911
      for (insn = insns; insn; insn = NEXT_INSN (insn))
3912
        if (CALL_P (insn))
3913
          {
3914
            rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3915
            if (note)
3916
              {
3917
                int lp_nr = INTVAL (XEXP (note, 0));
3918
                if (lp_nr == 0 || lp_nr == INT_MIN)
3919
                  remove_note (insn, note);
3920
              }
3921
          }
3922
    }
3923
  else
3924
    {
3925
      /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3926
         reg note to indicate that this call cannot throw or execute a nonlocal
3927
         goto (unless there is already a REG_EH_REGION note, in which case
3928
         we update it).  */
3929
      for (insn = insns; insn; insn = NEXT_INSN (insn))
3930
        if (CALL_P (insn))
3931
          make_reg_eh_region_note_nothrow_nononlocal (insn);
3932
    }
3933
 
3934
  /* First emit all insns that set pseudos.  Remove them from the list as
3935
     we go.  Avoid insns that set pseudos which were referenced in previous
3936
     insns.  These can be generated by move_by_pieces, for example,
3937
     to update an address.  Similarly, avoid insns that reference things
3938
     set in previous insns.  */
3939
 
3940
  for (insn = insns; insn; insn = next)
3941
    {
3942
      rtx set = single_set (insn);
3943
 
3944
      next = NEXT_INSN (insn);
3945
 
3946
      if (set != 0 && REG_P (SET_DEST (set))
3947
          && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3948
        {
3949
          struct no_conflict_data data;
3950
 
3951
          data.target = const0_rtx;
3952
          data.first = insns;
3953
          data.insn = insn;
3954
          data.must_stay = 0;
3955
          note_stores (PATTERN (insn), no_conflict_move_test, &data);
3956
          if (! data.must_stay)
3957
            {
3958
              if (PREV_INSN (insn))
3959
                NEXT_INSN (PREV_INSN (insn)) = next;
3960
              else
3961
                insns = next;
3962
 
3963
              if (next)
3964
                PREV_INSN (next) = PREV_INSN (insn);
3965
 
3966
              add_insn (insn);
3967
            }
3968
        }
3969
 
3970
      /* Some ports use a loop to copy large arguments onto the stack.
3971
         Don't move anything outside such a loop.  */
3972
      if (LABEL_P (insn))
3973
        break;
3974
    }
3975
 
3976
  /* Write the remaining insns followed by the final copy.  */
3977
  for (insn = insns; insn; insn = next)
3978
    {
3979
      next = NEXT_INSN (insn);
3980
 
3981
      add_insn (insn);
3982
    }
3983
 
3984
  last = emit_move_insn (target, result);
3985
  if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3986
      != CODE_FOR_nothing)
3987
    set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3988
 
3989
  if (final_dest != target)
3990
    emit_move_insn (final_dest, target);
3991
}
3992
 
3993
/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3994
   PURPOSE describes how this comparison will be used.  CODE is the rtx
3995
   comparison code we will be using.
3996
 
3997
   ??? Actually, CODE is slightly weaker than that.  A target is still
3998
   required to implement all of the normal bcc operations, but not
3999
   required to implement all (or any) of the unordered bcc operations.  */
4000
 
4001
int
4002
can_compare_p (enum rtx_code code, enum machine_mode mode,
4003
               enum can_compare_purpose purpose)
4004
{
4005
  rtx test;
4006
  test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
4007
  do
4008
    {
4009
      int icode;
4010
 
4011
      if (purpose == ccp_jump
4012
          && (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing
4013
          && insn_data[icode].operand[0].predicate (test, mode))
4014
        return 1;
4015
      if (purpose == ccp_store_flag
4016
          && (icode = optab_handler (cstore_optab, mode)->insn_code) != CODE_FOR_nothing
4017
          && insn_data[icode].operand[1].predicate (test, mode))
4018
        return 1;
4019
      if (purpose == ccp_cmov
4020
          && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
4021
        return 1;
4022
 
4023
      mode = GET_MODE_WIDER_MODE (mode);
4024
      PUT_MODE (test, mode);
4025
    }
4026
  while (mode != VOIDmode);
4027
 
4028
  return 0;
4029
}
4030
 
4031
/* This function is called when we are going to emit a compare instruction that
4032
   compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4033
 
4034
   *PMODE is the mode of the inputs (in case they are const_int).
4035
   *PUNSIGNEDP nonzero says that the operands are unsigned;
4036
   this matters if they need to be widened (as given by METHODS).
4037
 
4038
   If they have mode BLKmode, then SIZE specifies the size of both operands.
4039
 
4040
   This function performs all the setup necessary so that the caller only has
4041
   to emit a single comparison insn.  This setup can involve doing a BLKmode
4042
   comparison or emitting a library call to perform the comparison if no insn
4043
   is available to handle it.
4044
   The values which are passed in through pointers can be modified; the caller
4045
   should perform the comparison on the modified values.  Constant
4046
   comparisons must have already been folded.  */
4047
 
4048
static void
4049
prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4050
                  int unsignedp, enum optab_methods methods,
4051
                  rtx *ptest, enum machine_mode *pmode)
4052
{
4053
  enum machine_mode mode = *pmode;
4054
  rtx libfunc, test;
4055
  enum machine_mode cmp_mode;
4056
  enum mode_class mclass;
4057
 
4058
  /* The other methods are not needed.  */
4059
  gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4060
              || methods == OPTAB_LIB_WIDEN);
4061
 
4062
  /* If we are optimizing, force expensive constants into a register.  */
4063
  if (CONSTANT_P (x) && optimize
4064
      && (rtx_cost (x, COMPARE, optimize_insn_for_speed_p ())
4065
          > COSTS_N_INSNS (1)))
4066
    x = force_reg (mode, x);
4067
 
4068
  if (CONSTANT_P (y) && optimize
4069
      && (rtx_cost (y, COMPARE, optimize_insn_for_speed_p ())
4070
          > COSTS_N_INSNS (1)))
4071
    y = force_reg (mode, y);
4072
 
4073
#ifdef HAVE_cc0
4074
  /* Make sure if we have a canonical comparison.  The RTL
4075
     documentation states that canonical comparisons are required only
4076
     for targets which have cc0.  */
4077
  gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4078
#endif
4079
 
4080
  /* Don't let both operands fail to indicate the mode.  */
4081
  if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4082
    x = force_reg (mode, x);
4083
  if (mode == VOIDmode)
4084
    mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4085
 
4086
  /* Handle all BLKmode compares.  */
4087
 
4088
  if (mode == BLKmode)
4089
    {
4090
      enum machine_mode result_mode;
4091
      enum insn_code cmp_code;
4092
      tree length_type;
4093
      rtx libfunc;
4094
      rtx result;
4095
      rtx opalign
4096
        = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4097
 
4098
      gcc_assert (size);
4099
 
4100
      /* Try to use a memory block compare insn - either cmpstr
4101
         or cmpmem will do.  */
4102
      for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4103
           cmp_mode != VOIDmode;
4104
           cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4105
        {
4106
          cmp_code = cmpmem_optab[cmp_mode];
4107
          if (cmp_code == CODE_FOR_nothing)
4108
            cmp_code = cmpstr_optab[cmp_mode];
4109
          if (cmp_code == CODE_FOR_nothing)
4110
            cmp_code = cmpstrn_optab[cmp_mode];
4111
          if (cmp_code == CODE_FOR_nothing)
4112
            continue;
4113
 
4114
          /* Must make sure the size fits the insn's mode.  */
4115
          if ((CONST_INT_P (size)
4116
               && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4117
              || (GET_MODE_BITSIZE (GET_MODE (size))
4118
                  > GET_MODE_BITSIZE (cmp_mode)))
4119
            continue;
4120
 
4121
          result_mode = insn_data[cmp_code].operand[0].mode;
4122
          result = gen_reg_rtx (result_mode);
4123
          size = convert_to_mode (cmp_mode, size, 1);
4124
          emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4125
 
4126
          *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4127
          *pmode = result_mode;
4128
          return;
4129
        }
4130
 
4131
      if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4132
        goto fail;
4133
 
4134
      /* Otherwise call a library function, memcmp.  */
4135
      libfunc = memcmp_libfunc;
4136
      length_type = sizetype;
4137
      result_mode = TYPE_MODE (integer_type_node);
4138
      cmp_mode = TYPE_MODE (length_type);
4139
      size = convert_to_mode (TYPE_MODE (length_type), size,
4140
                              TYPE_UNSIGNED (length_type));
4141
 
4142
      result = emit_library_call_value (libfunc, 0, LCT_PURE,
4143
                                        result_mode, 3,
4144
                                        XEXP (x, 0), Pmode,
4145
                                        XEXP (y, 0), Pmode,
4146
                                        size, cmp_mode);
4147
 
4148
      *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4149
      *pmode = result_mode;
4150
      return;
4151
    }
4152
 
4153
  /* Don't allow operands to the compare to trap, as that can put the
4154
     compare and branch in different basic blocks.  */
4155
  if (flag_non_call_exceptions)
4156
    {
4157
      if (may_trap_p (x))
4158
        x = force_reg (mode, x);
4159
      if (may_trap_p (y))
4160
        y = force_reg (mode, y);
4161
    }
4162
 
4163
  if (GET_MODE_CLASS (mode) == MODE_CC)
4164
    {
4165
      gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
4166
      *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4167
      return;
4168
    }
4169
 
4170
  mclass = GET_MODE_CLASS (mode);
4171
  test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4172
  cmp_mode = mode;
4173
  do
4174
   {
4175
      enum insn_code icode;
4176
      icode = optab_handler (cbranch_optab, cmp_mode)->insn_code;
4177
      if (icode != CODE_FOR_nothing
4178
          && insn_data[icode].operand[0].predicate (test, VOIDmode))
4179
        {
4180
          rtx last = get_last_insn ();
4181
          rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4182
          rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4183
          if (op0 && op1
4184
              && insn_data[icode].operand[1].predicate
4185
                 (op0, insn_data[icode].operand[1].mode)
4186
              && insn_data[icode].operand[2].predicate
4187
                 (op1, insn_data[icode].operand[2].mode))
4188
            {
4189
              XEXP (test, 0) = op0;
4190
              XEXP (test, 1) = op1;
4191
              *ptest = test;
4192
              *pmode = cmp_mode;
4193
              return;
4194
            }
4195
          delete_insns_since (last);
4196
        }
4197
 
4198
      if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4199
        break;
4200
      cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
4201
    }
4202
  while (cmp_mode != VOIDmode);
4203
 
4204
  if (methods != OPTAB_LIB_WIDEN)
4205
    goto fail;
4206
 
4207
  if (!SCALAR_FLOAT_MODE_P (mode))
4208
    {
4209
      rtx result;
4210
 
4211
      /* Handle a libcall just for the mode we are using.  */
4212
      libfunc = optab_libfunc (cmp_optab, mode);
4213
      gcc_assert (libfunc);
4214
 
4215
      /* If we want unsigned, and this mode has a distinct unsigned
4216
         comparison routine, use that.  */
4217
      if (unsignedp)
4218
        {
4219
          rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4220
          if (ulibfunc)
4221
            libfunc = ulibfunc;
4222
        }
4223
 
4224
      result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4225
                                        targetm.libgcc_cmp_return_mode (),
4226
                                        2, x, mode, y, mode);
4227
 
4228
      /* There are two kinds of comparison routines. Biased routines
4229
         return 0/1/2, and unbiased routines return -1/0/1. Other parts
4230
         of gcc expect that the comparison operation is equivalent
4231
         to the modified comparison. For signed comparisons compare the
4232
         result against 1 in the biased case, and zero in the unbiased
4233
         case. For unsigned comparisons always compare against 1 after
4234
         biasing the unbiased result by adding 1. This gives us a way to
4235
         represent LTU. */
4236
      x = result;
4237
      y = const1_rtx;
4238
 
4239
      if (!TARGET_LIB_INT_CMP_BIASED)
4240
        {
4241
          if (unsignedp)
4242
            x = plus_constant (result, 1);
4243
          else
4244
            y = const0_rtx;
4245
        }
4246
 
4247
      *pmode = word_mode;
4248
      prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4249
                        ptest, pmode);
4250
    }
4251
  else
4252
    prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4253
 
4254
  return;
4255
 
4256
 fail:
4257
  *ptest = NULL_RTX;
4258
}
4259
 
4260
/* Before emitting an insn with code ICODE, make sure that X, which is going
4261
   to be used for operand OPNUM of the insn, is converted from mode MODE to
4262
   WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4263
   that it is accepted by the operand predicate.  Return the new value.  */
4264
 
4265
rtx
4266
prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
4267
                 enum machine_mode wider_mode, int unsignedp)
4268
{
4269
  if (mode != wider_mode)
4270
    x = convert_modes (wider_mode, mode, x, unsignedp);
4271
 
4272
  if (!insn_data[icode].operand[opnum].predicate
4273
      (x, insn_data[icode].operand[opnum].mode))
4274
    {
4275
      if (reload_completed)
4276
        return NULL_RTX;
4277
      x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
4278
    }
4279
 
4280
  return x;
4281
}
4282
 
4283
/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4284
   we can do the branch.  */
4285
 
4286
static void
4287
emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
4288
{
4289
  enum machine_mode optab_mode;
4290
  enum mode_class mclass;
4291
  enum insn_code icode;
4292
 
4293
  mclass = GET_MODE_CLASS (mode);
4294
  optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4295
  icode = optab_handler (cbranch_optab, optab_mode)->insn_code;
4296
 
4297
  gcc_assert (icode != CODE_FOR_nothing);
4298
  gcc_assert (insn_data[icode].operand[0].predicate (test, VOIDmode));
4299
  emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0), XEXP (test, 1), label));
4300
}
4301
 
4302
/* Generate code to compare X with Y so that the condition codes are
4303
   set and to jump to LABEL if the condition is true.  If X is a
4304
   constant and Y is not a constant, then the comparison is swapped to
4305
   ensure that the comparison RTL has the canonical form.
4306
 
4307
   UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4308
   need to be widened.  UNSIGNEDP is also used to select the proper
4309
   branch condition code.
4310
 
4311
   If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4312
 
4313
   MODE is the mode of the inputs (in case they are const_int).
4314
 
4315
   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4316
   It will be potentially converted into an unsigned variant based on
4317
   UNSIGNEDP to select a proper jump instruction.  */
4318
 
4319
void
4320
emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4321
                         enum machine_mode mode, int unsignedp, rtx label)
4322
{
4323
  rtx op0 = x, op1 = y;
4324
  rtx test;
4325
 
4326
  /* Swap operands and condition to ensure canonical RTL.  */
4327
  if (swap_commutative_operands_p (x, y)
4328
      && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4329
    {
4330
      op0 = y, op1 = x;
4331
      comparison = swap_condition (comparison);
4332
    }
4333
 
4334
  /* If OP0 is still a constant, then both X and Y must be constants
4335
     or the opposite comparison is not supported.  Force X into a register
4336
     to create canonical RTL.  */
4337
  if (CONSTANT_P (op0))
4338
    op0 = force_reg (mode, op0);
4339
 
4340
  if (unsignedp)
4341
    comparison = unsigned_condition (comparison);
4342
 
4343
  prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4344
                    &test, &mode);
4345
  emit_cmp_and_jump_insn_1 (test, mode, label);
4346
}
4347
 
4348
 
4349
/* Emit a library call comparison between floating point X and Y.
4350
   COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
4351
 
4352
static void
4353
prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4354
                       rtx *ptest, enum machine_mode *pmode)
4355
{
4356
  enum rtx_code swapped = swap_condition (comparison);
4357
  enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4358
  enum machine_mode orig_mode = GET_MODE (x);
4359
  enum machine_mode mode, cmp_mode;
4360
  rtx value, target, insns, equiv;
4361
  rtx libfunc = 0;
4362
  bool reversed_p = false;
4363
  cmp_mode = targetm.libgcc_cmp_return_mode ();
4364
 
4365
  for (mode = orig_mode;
4366
       mode != VOIDmode;
4367
       mode = GET_MODE_WIDER_MODE (mode))
4368
    {
4369
      if (code_to_optab[comparison]
4370
          && (libfunc = optab_libfunc (code_to_optab[comparison], mode)))
4371
        break;
4372
 
4373
      if (code_to_optab[swapped]
4374
          && (libfunc = optab_libfunc (code_to_optab[swapped], mode)))
4375
        {
4376
          rtx tmp;
4377
          tmp = x; x = y; y = tmp;
4378
          comparison = swapped;
4379
          break;
4380
        }
4381
 
4382
      if (code_to_optab[reversed]
4383
          && (libfunc = optab_libfunc (code_to_optab[reversed], mode))
4384
          && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4385
        {
4386
          comparison = reversed;
4387
          reversed_p = true;
4388
          break;
4389
        }
4390
    }
4391
 
4392
  gcc_assert (mode != VOIDmode);
4393
 
4394
  if (mode != orig_mode)
4395
    {
4396
      x = convert_to_mode (mode, x, 0);
4397
      y = convert_to_mode (mode, y, 0);
4398
    }
4399
 
4400
  /* Attach a REG_EQUAL note describing the semantics of the libcall to
4401
     the RTL.  The allows the RTL optimizers to delete the libcall if the
4402
     condition can be determined at compile-time.  */
4403
  if (comparison == UNORDERED)
4404
    {
4405
      rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4406
      equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4407
      equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4408
                                    temp, const_true_rtx, equiv);
4409
    }
4410
  else
4411
    {
4412
      equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4413
      if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4414
        {
4415
          rtx true_rtx, false_rtx;
4416
 
4417
          switch (comparison)
4418
            {
4419
            case EQ:
4420
              true_rtx = const0_rtx;
4421
              false_rtx = const_true_rtx;
4422
              break;
4423
 
4424
            case NE:
4425
              true_rtx = const_true_rtx;
4426
              false_rtx = const0_rtx;
4427
              break;
4428
 
4429
            case GT:
4430
              true_rtx = const1_rtx;
4431
              false_rtx = const0_rtx;
4432
              break;
4433
 
4434
            case GE:
4435
              true_rtx = const0_rtx;
4436
              false_rtx = constm1_rtx;
4437
              break;
4438
 
4439
            case LT:
4440
              true_rtx = constm1_rtx;
4441
              false_rtx = const0_rtx;
4442
              break;
4443
 
4444
            case LE:
4445
              true_rtx = const0_rtx;
4446
              false_rtx = const1_rtx;
4447
              break;
4448
 
4449
            default:
4450
              gcc_unreachable ();
4451
            }
4452
          equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4453
                                        equiv, true_rtx, false_rtx);
4454
        }
4455
    }
4456
 
4457
  start_sequence ();
4458
  value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4459
                                   cmp_mode, 2, x, mode, y, mode);
4460
  insns = get_insns ();
4461
  end_sequence ();
4462
 
4463
  target = gen_reg_rtx (cmp_mode);
4464
  emit_libcall_block (insns, target, value, equiv);
4465
 
4466
  if (comparison == UNORDERED
4467
      || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4468
    comparison = reversed_p ? EQ : NE;
4469
 
4470
  *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4471
  *pmode = cmp_mode;
4472
}
4473
 
4474
/* Generate code to indirectly jump to a location given in the rtx LOC.  */
4475
 
4476
void
4477
emit_indirect_jump (rtx loc)
4478
{
4479
  if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4480
      (loc, Pmode))
4481
    loc = copy_to_mode_reg (Pmode, loc);
4482
 
4483
  emit_jump_insn (gen_indirect_jump (loc));
4484
  emit_barrier ();
4485
}
4486
 
4487
#ifdef HAVE_conditional_move
4488
 
4489
/* Emit a conditional move instruction if the machine supports one for that
4490
   condition and machine mode.
4491
 
4492
   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4493
   the mode to use should they be constants.  If it is VOIDmode, they cannot
4494
   both be constants.
4495
 
4496
   OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4497
   should be stored there.  MODE is the mode to use should they be constants.
4498
   If it is VOIDmode, they cannot both be constants.
4499
 
4500
   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4501
   is not supported.  */
4502
 
4503
rtx
4504
emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4505
                       enum machine_mode cmode, rtx op2, rtx op3,
4506
                       enum machine_mode mode, int unsignedp)
4507
{
4508
  rtx tem, subtarget, comparison, insn;
4509
  enum insn_code icode;
4510
  enum rtx_code reversed;
4511
 
4512
  /* If one operand is constant, make it the second one.  Only do this
4513
     if the other operand is not constant as well.  */
4514
 
4515
  if (swap_commutative_operands_p (op0, op1))
4516
    {
4517
      tem = op0;
4518
      op0 = op1;
4519
      op1 = tem;
4520
      code = swap_condition (code);
4521
    }
4522
 
4523
  /* get_condition will prefer to generate LT and GT even if the old
4524
     comparison was against zero, so undo that canonicalization here since
4525
     comparisons against zero are cheaper.  */
4526
  if (code == LT && op1 == const1_rtx)
4527
    code = LE, op1 = const0_rtx;
4528
  else if (code == GT && op1 == constm1_rtx)
4529
    code = GE, op1 = const0_rtx;
4530
 
4531
  if (cmode == VOIDmode)
4532
    cmode = GET_MODE (op0);
4533
 
4534
  if (swap_commutative_operands_p (op2, op3)
4535
      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4536
          != UNKNOWN))
4537
    {
4538
      tem = op2;
4539
      op2 = op3;
4540
      op3 = tem;
4541
      code = reversed;
4542
    }
4543
 
4544
  if (mode == VOIDmode)
4545
    mode = GET_MODE (op2);
4546
 
4547
  icode = movcc_gen_code[mode];
4548
 
4549
  if (icode == CODE_FOR_nothing)
4550
    return 0;
4551
 
4552
  if (!target)
4553
    target = gen_reg_rtx (mode);
4554
 
4555
  subtarget = target;
4556
 
4557
  /* If the insn doesn't accept these operands, put them in pseudos.  */
4558
 
4559
  if (!insn_data[icode].operand[0].predicate
4560
      (subtarget, insn_data[icode].operand[0].mode))
4561
    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4562
 
4563
  if (!insn_data[icode].operand[2].predicate
4564
      (op2, insn_data[icode].operand[2].mode))
4565
    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4566
 
4567
  if (!insn_data[icode].operand[3].predicate
4568
      (op3, insn_data[icode].operand[3].mode))
4569
    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4570
 
4571
  /* Everything should now be in the suitable form.  */
4572
 
4573
  code = unsignedp ? unsigned_condition (code) : code;
4574
  comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4575
 
4576
  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4577
     return NULL and let the caller figure out how best to deal with this
4578
     situation.  */
4579
  if (!COMPARISON_P (comparison))
4580
    return NULL_RTX;
4581
 
4582
  do_pending_stack_adjust ();
4583
  start_sequence ();
4584
  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4585
                    GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4586
                    &comparison, &cmode);
4587
  if (!comparison)
4588
    insn = NULL_RTX;
4589
  else
4590
    insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4591
 
4592
  /* If that failed, then give up.  */
4593
  if (insn == 0)
4594
    {
4595
      end_sequence ();
4596
      return 0;
4597
    }
4598
 
4599
  emit_insn (insn);
4600
  insn = get_insns ();
4601
  end_sequence ();
4602
  emit_insn (insn);
4603
  if (subtarget != target)
4604
    convert_move (target, subtarget, 0);
4605
 
4606
  return target;
4607
}
4608
 
4609
/* Return nonzero if a conditional move of mode MODE is supported.
4610
 
4611
   This function is for combine so it can tell whether an insn that looks
4612
   like a conditional move is actually supported by the hardware.  If we
4613
   guess wrong we lose a bit on optimization, but that's it.  */
4614
/* ??? sparc64 supports conditionally moving integers values based on fp
4615
   comparisons, and vice versa.  How do we handle them?  */
4616
 
4617
int
4618
can_conditionally_move_p (enum machine_mode mode)
4619
{
4620
  if (movcc_gen_code[mode] != CODE_FOR_nothing)
4621
    return 1;
4622
 
4623
  return 0;
4624
}
4625
 
4626
#endif /* HAVE_conditional_move */
4627
 
4628
/* Emit a conditional addition instruction if the machine supports one for that
4629
   condition and machine mode.
4630
 
4631
   OP0 and OP1 are the operands that should be compared using CODE.  CMODE is
4632
   the mode to use should they be constants.  If it is VOIDmode, they cannot
4633
   both be constants.
4634
 
4635
   OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4636
   should be stored there.  MODE is the mode to use should they be constants.
4637
   If it is VOIDmode, they cannot both be constants.
4638
 
4639
   The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4640
   is not supported.  */
4641
 
4642
rtx
4643
emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4644
                      enum machine_mode cmode, rtx op2, rtx op3,
4645
                      enum machine_mode mode, int unsignedp)
4646
{
4647
  rtx tem, subtarget, comparison, insn;
4648
  enum insn_code icode;
4649
  enum rtx_code reversed;
4650
 
4651
  /* If one operand is constant, make it the second one.  Only do this
4652
     if the other operand is not constant as well.  */
4653
 
4654
  if (swap_commutative_operands_p (op0, op1))
4655
    {
4656
      tem = op0;
4657
      op0 = op1;
4658
      op1 = tem;
4659
      code = swap_condition (code);
4660
    }
4661
 
4662
  /* get_condition will prefer to generate LT and GT even if the old
4663
     comparison was against zero, so undo that canonicalization here since
4664
     comparisons against zero are cheaper.  */
4665
  if (code == LT && op1 == const1_rtx)
4666
    code = LE, op1 = const0_rtx;
4667
  else if (code == GT && op1 == constm1_rtx)
4668
    code = GE, op1 = const0_rtx;
4669
 
4670
  if (cmode == VOIDmode)
4671
    cmode = GET_MODE (op0);
4672
 
4673
  if (swap_commutative_operands_p (op2, op3)
4674
      && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4675
          != UNKNOWN))
4676
    {
4677
      tem = op2;
4678
      op2 = op3;
4679
      op3 = tem;
4680
      code = reversed;
4681
    }
4682
 
4683
  if (mode == VOIDmode)
4684
    mode = GET_MODE (op2);
4685
 
4686
  icode = optab_handler (addcc_optab, mode)->insn_code;
4687
 
4688
  if (icode == CODE_FOR_nothing)
4689
    return 0;
4690
 
4691
  if (!target)
4692
    target = gen_reg_rtx (mode);
4693
 
4694
  /* If the insn doesn't accept these operands, put them in pseudos.  */
4695
 
4696
  if (!insn_data[icode].operand[0].predicate
4697
      (target, insn_data[icode].operand[0].mode))
4698
    subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4699
  else
4700
    subtarget = target;
4701
 
4702
  if (!insn_data[icode].operand[2].predicate
4703
      (op2, insn_data[icode].operand[2].mode))
4704
    op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4705
 
4706
  if (!insn_data[icode].operand[3].predicate
4707
      (op3, insn_data[icode].operand[3].mode))
4708
    op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4709
 
4710
  /* Everything should now be in the suitable form.  */
4711
 
4712
  code = unsignedp ? unsigned_condition (code) : code;
4713
  comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4714
 
4715
  /* We can get const0_rtx or const_true_rtx in some circumstances.  Just
4716
     return NULL and let the caller figure out how best to deal with this
4717
     situation.  */
4718
  if (!COMPARISON_P (comparison))
4719
    return NULL_RTX;
4720
 
4721
  do_pending_stack_adjust ();
4722
  start_sequence ();
4723
  prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4724
                    GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4725
                    &comparison, &cmode);
4726
  if (!comparison)
4727
    insn = NULL_RTX;
4728
  else
4729
    insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4730
 
4731
  /* If that failed, then give up.  */
4732
  if (insn == 0)
4733
    {
4734
      end_sequence ();
4735
      return 0;
4736
    }
4737
 
4738
  emit_insn (insn);
4739
  insn = get_insns ();
4740
  end_sequence ();
4741
  emit_insn (insn);
4742
  if (subtarget != target)
4743
    convert_move (target, subtarget, 0);
4744
 
4745
  return target;
4746
}
4747
 
4748
/* These functions attempt to generate an insn body, rather than
4749
   emitting the insn, but if the gen function already emits them, we
4750
   make no attempt to turn them back into naked patterns.  */
4751
 
4752
/* Generate and return an insn body to add Y to X.  */
4753
 
4754
rtx
4755
gen_add2_insn (rtx x, rtx y)
4756
{
4757
  int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4758
 
4759
  gcc_assert (insn_data[icode].operand[0].predicate
4760
              (x, insn_data[icode].operand[0].mode));
4761
  gcc_assert (insn_data[icode].operand[1].predicate
4762
              (x, insn_data[icode].operand[1].mode));
4763
  gcc_assert (insn_data[icode].operand[2].predicate
4764
              (y, insn_data[icode].operand[2].mode));
4765
 
4766
  return GEN_FCN (icode) (x, x, y);
4767
}
4768
 
4769
/* Generate and return an insn body to add r1 and c,
4770
   storing the result in r0.  */
4771
 
4772
rtx
4773
gen_add3_insn (rtx r0, rtx r1, rtx c)
4774
{
4775
  int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code;
4776
 
4777
  if (icode == CODE_FOR_nothing
4778
      || !(insn_data[icode].operand[0].predicate
4779
           (r0, insn_data[icode].operand[0].mode))
4780
      || !(insn_data[icode].operand[1].predicate
4781
           (r1, insn_data[icode].operand[1].mode))
4782
      || !(insn_data[icode].operand[2].predicate
4783
           (c, insn_data[icode].operand[2].mode)))
4784
    return NULL_RTX;
4785
 
4786
  return GEN_FCN (icode) (r0, r1, c);
4787
}
4788
 
4789
int
4790
have_add2_insn (rtx x, rtx y)
4791
{
4792
  int icode;
4793
 
4794
  gcc_assert (GET_MODE (x) != VOIDmode);
4795
 
4796
  icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4797
 
4798
  if (icode == CODE_FOR_nothing)
4799
    return 0;
4800
 
4801
  if (!(insn_data[icode].operand[0].predicate
4802
        (x, insn_data[icode].operand[0].mode))
4803
      || !(insn_data[icode].operand[1].predicate
4804
           (x, insn_data[icode].operand[1].mode))
4805
      || !(insn_data[icode].operand[2].predicate
4806
           (y, insn_data[icode].operand[2].mode)))
4807
    return 0;
4808
 
4809
  return 1;
4810
}
4811
 
4812
/* Generate and return an insn body to subtract Y from X.  */
4813
 
4814
rtx
4815
gen_sub2_insn (rtx x, rtx y)
4816
{
4817
  int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4818
 
4819
  gcc_assert (insn_data[icode].operand[0].predicate
4820
              (x, insn_data[icode].operand[0].mode));
4821
  gcc_assert (insn_data[icode].operand[1].predicate
4822
              (x, insn_data[icode].operand[1].mode));
4823
  gcc_assert  (insn_data[icode].operand[2].predicate
4824
               (y, insn_data[icode].operand[2].mode));
4825
 
4826
  return GEN_FCN (icode) (x, x, y);
4827
}
4828
 
4829
/* Generate and return an insn body to subtract r1 and c,
4830
   storing the result in r0.  */
4831
 
4832
rtx
4833
gen_sub3_insn (rtx r0, rtx r1, rtx c)
4834
{
4835
  int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code;
4836
 
4837
  if (icode == CODE_FOR_nothing
4838
      || !(insn_data[icode].operand[0].predicate
4839
           (r0, insn_data[icode].operand[0].mode))
4840
      || !(insn_data[icode].operand[1].predicate
4841
           (r1, insn_data[icode].operand[1].mode))
4842
      || !(insn_data[icode].operand[2].predicate
4843
           (c, insn_data[icode].operand[2].mode)))
4844
    return NULL_RTX;
4845
 
4846
  return GEN_FCN (icode) (r0, r1, c);
4847
}
4848
 
4849
int
4850
have_sub2_insn (rtx x, rtx y)
4851
{
4852
  int icode;
4853
 
4854
  gcc_assert (GET_MODE (x) != VOIDmode);
4855
 
4856
  icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4857
 
4858
  if (icode == CODE_FOR_nothing)
4859
    return 0;
4860
 
4861
  if (!(insn_data[icode].operand[0].predicate
4862
        (x, insn_data[icode].operand[0].mode))
4863
      || !(insn_data[icode].operand[1].predicate
4864
           (x, insn_data[icode].operand[1].mode))
4865
      || !(insn_data[icode].operand[2].predicate
4866
           (y, insn_data[icode].operand[2].mode)))
4867
    return 0;
4868
 
4869
  return 1;
4870
}
4871
 
4872
/* Generate the body of an instruction to copy Y into X.
4873
   It may be a list of insns, if one insn isn't enough.  */
4874
 
4875
rtx
4876
gen_move_insn (rtx x, rtx y)
4877
{
4878
  rtx seq;
4879
 
4880
  start_sequence ();
4881
  emit_move_insn_1 (x, y);
4882
  seq = get_insns ();
4883
  end_sequence ();
4884
  return seq;
4885
}
4886
 
4887
/* Return the insn code used to extend FROM_MODE to TO_MODE.
4888
   UNSIGNEDP specifies zero-extension instead of sign-extension.  If
4889
   no such operation exists, CODE_FOR_nothing will be returned.  */
4890
 
4891
enum insn_code
4892
can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4893
              int unsignedp)
4894
{
4895
  convert_optab tab;
4896
#ifdef HAVE_ptr_extend
4897
  if (unsignedp < 0)
4898
    return CODE_FOR_ptr_extend;
4899
#endif
4900
 
4901
  tab = unsignedp ? zext_optab : sext_optab;
4902
  return convert_optab_handler (tab, to_mode, from_mode)->insn_code;
4903
}
4904
 
4905
/* Generate the body of an insn to extend Y (with mode MFROM)
4906
   into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
4907
 
4908
rtx
4909
gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4910
                 enum machine_mode mfrom, int unsignedp)
4911
{
4912
  enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4913
  return GEN_FCN (icode) (x, y);
4914
}
4915
 
4916
/* can_fix_p and can_float_p say whether the target machine
4917
   can directly convert a given fixed point type to
4918
   a given floating point type, or vice versa.
4919
   The returned value is the CODE_FOR_... value to use,
4920
   or CODE_FOR_nothing if these modes cannot be directly converted.
4921
 
4922
   *TRUNCP_PTR is set to 1 if it is necessary to output
4923
   an explicit FTRUNC insn before the fix insn; otherwise 0.  */
4924
 
4925
static enum insn_code
4926
can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4927
           int unsignedp, int *truncp_ptr)
4928
{
4929
  convert_optab tab;
4930
  enum insn_code icode;
4931
 
4932
  tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4933
  icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4934
  if (icode != CODE_FOR_nothing)
4935
    {
4936
      *truncp_ptr = 0;
4937
      return icode;
4938
    }
4939
 
4940
  /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4941
     for this to work. We need to rework the fix* and ftrunc* patterns
4942
     and documentation.  */
4943
  tab = unsignedp ? ufix_optab : sfix_optab;
4944
  icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4945
  if (icode != CODE_FOR_nothing
4946
      && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing)
4947
    {
4948
      *truncp_ptr = 1;
4949
      return icode;
4950
    }
4951
 
4952
  *truncp_ptr = 0;
4953
  return CODE_FOR_nothing;
4954
}
4955
 
4956
static enum insn_code
4957
can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4958
             int unsignedp)
4959
{
4960
  convert_optab tab;
4961
 
4962
  tab = unsignedp ? ufloat_optab : sfloat_optab;
4963
  return convert_optab_handler (tab, fltmode, fixmode)->insn_code;
4964
}
4965
 
4966
/* Generate code to convert FROM to floating point
4967
   and store in TO.  FROM must be fixed point and not VOIDmode.
4968
   UNSIGNEDP nonzero means regard FROM as unsigned.
4969
   Normally this is done by correcting the final value
4970
   if it is negative.  */
4971
 
4972
void
4973
expand_float (rtx to, rtx from, int unsignedp)
4974
{
4975
  enum insn_code icode;
4976
  rtx target = to;
4977
  enum machine_mode fmode, imode;
4978
  bool can_do_signed = false;
4979
 
4980
  /* Crash now, because we won't be able to decide which mode to use.  */
4981
  gcc_assert (GET_MODE (from) != VOIDmode);
4982
 
4983
  /* Look for an insn to do the conversion.  Do it in the specified
4984
     modes if possible; otherwise convert either input, output or both to
4985
     wider mode.  If the integer mode is wider than the mode of FROM,
4986
     we can do the conversion signed even if the input is unsigned.  */
4987
 
4988
  for (fmode = GET_MODE (to); fmode != VOIDmode;
4989
       fmode = GET_MODE_WIDER_MODE (fmode))
4990
    for (imode = GET_MODE (from); imode != VOIDmode;
4991
         imode = GET_MODE_WIDER_MODE (imode))
4992
      {
4993
        int doing_unsigned = unsignedp;
4994
 
4995
        if (fmode != GET_MODE (to)
4996
            && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4997
          continue;
4998
 
4999
        icode = can_float_p (fmode, imode, unsignedp);
5000
        if (icode == CODE_FOR_nothing && unsignedp)
5001
          {
5002
            enum insn_code scode = can_float_p (fmode, imode, 0);
5003
            if (scode != CODE_FOR_nothing)
5004
              can_do_signed = true;
5005
            if (imode != GET_MODE (from))
5006
              icode = scode, doing_unsigned = 0;
5007
          }
5008
 
5009
        if (icode != CODE_FOR_nothing)
5010
          {
5011
            if (imode != GET_MODE (from))
5012
              from = convert_to_mode (imode, from, unsignedp);
5013
 
5014
            if (fmode != GET_MODE (to))
5015
              target = gen_reg_rtx (fmode);
5016
 
5017
            emit_unop_insn (icode, target, from,
5018
                            doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5019
 
5020
            if (target != to)
5021
              convert_move (to, target, 0);
5022
            return;
5023
          }
5024
      }
5025
 
5026
  /* Unsigned integer, and no way to convert directly.  Convert as signed,
5027
     then unconditionally adjust the result.  */
5028
  if (unsignedp && can_do_signed)
5029
    {
5030
      rtx label = gen_label_rtx ();
5031
      rtx temp;
5032
      REAL_VALUE_TYPE offset;
5033
 
5034
      /* Look for a usable floating mode FMODE wider than the source and at
5035
         least as wide as the target.  Using FMODE will avoid rounding woes
5036
         with unsigned values greater than the signed maximum value.  */
5037
 
5038
      for (fmode = GET_MODE (to);  fmode != VOIDmode;
5039
           fmode = GET_MODE_WIDER_MODE (fmode))
5040
        if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5041
            && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5042
          break;
5043
 
5044
      if (fmode == VOIDmode)
5045
        {
5046
          /* There is no such mode.  Pretend the target is wide enough.  */
5047
          fmode = GET_MODE (to);
5048
 
5049
          /* Avoid double-rounding when TO is narrower than FROM.  */
5050
          if ((significand_size (fmode) + 1)
5051
              < GET_MODE_BITSIZE (GET_MODE (from)))
5052
            {
5053
              rtx temp1;
5054
              rtx neglabel = gen_label_rtx ();
5055
 
5056
              /* Don't use TARGET if it isn't a register, is a hard register,
5057
                 or is the wrong mode.  */
5058
              if (!REG_P (target)
5059
                  || REGNO (target) < FIRST_PSEUDO_REGISTER
5060
                  || GET_MODE (target) != fmode)
5061
                target = gen_reg_rtx (fmode);
5062
 
5063
              imode = GET_MODE (from);
5064
              do_pending_stack_adjust ();
5065
 
5066
              /* Test whether the sign bit is set.  */
5067
              emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5068
                                       0, neglabel);
5069
 
5070
              /* The sign bit is not set.  Convert as signed.  */
5071
              expand_float (target, from, 0);
5072
              emit_jump_insn (gen_jump (label));
5073
              emit_barrier ();
5074
 
5075
              /* The sign bit is set.
5076
                 Convert to a usable (positive signed) value by shifting right
5077
                 one bit, while remembering if a nonzero bit was shifted
5078
                 out; i.e., compute  (from & 1) | (from >> 1).  */
5079
 
5080
              emit_label (neglabel);
5081
              temp = expand_binop (imode, and_optab, from, const1_rtx,
5082
                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
5083
              temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
5084
                                    NULL_RTX, 1);
5085
              temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5086
                                   OPTAB_LIB_WIDEN);
5087
              expand_float (target, temp, 0);
5088
 
5089
              /* Multiply by 2 to undo the shift above.  */
5090
              temp = expand_binop (fmode, add_optab, target, target,
5091
                                   target, 0, OPTAB_LIB_WIDEN);
5092
              if (temp != target)
5093
                emit_move_insn (target, temp);
5094
 
5095
              do_pending_stack_adjust ();
5096
              emit_label (label);
5097
              goto done;
5098
            }
5099
        }
5100
 
5101
      /* If we are about to do some arithmetic to correct for an
5102
         unsigned operand, do it in a pseudo-register.  */
5103
 
5104
      if (GET_MODE (to) != fmode
5105
          || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5106
        target = gen_reg_rtx (fmode);
5107
 
5108
      /* Convert as signed integer to floating.  */
5109
      expand_float (target, from, 0);
5110
 
5111
      /* If FROM is negative (and therefore TO is negative),
5112
         correct its value by 2**bitwidth.  */
5113
 
5114
      do_pending_stack_adjust ();
5115
      emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5116
                               0, label);
5117
 
5118
 
5119
      real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)), fmode);
5120
      temp = expand_binop (fmode, add_optab, target,
5121
                           CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5122
                           target, 0, OPTAB_LIB_WIDEN);
5123
      if (temp != target)
5124
        emit_move_insn (target, temp);
5125
 
5126
      do_pending_stack_adjust ();
5127
      emit_label (label);
5128
      goto done;
5129
    }
5130
 
5131
  /* No hardware instruction available; call a library routine.  */
5132
    {
5133
      rtx libfunc;
5134
      rtx insns;
5135
      rtx value;
5136
      convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5137
 
5138
      if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5139
        from = convert_to_mode (SImode, from, unsignedp);
5140
 
5141
      libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5142
      gcc_assert (libfunc);
5143
 
5144
      start_sequence ();
5145
 
5146
      value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5147
                                       GET_MODE (to), 1, from,
5148
                                       GET_MODE (from));
5149
      insns = get_insns ();
5150
      end_sequence ();
5151
 
5152
      emit_libcall_block (insns, target, value,
5153
                          gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5154
                                         GET_MODE (to), from));
5155
    }
5156
 
5157
 done:
5158
 
5159
  /* Copy result to requested destination
5160
     if we have been computing in a temp location.  */
5161
 
5162
  if (target != to)
5163
    {
5164
      if (GET_MODE (target) == GET_MODE (to))
5165
        emit_move_insn (to, target);
5166
      else
5167
        convert_move (to, target, 0);
5168
    }
5169
}
5170
 
5171
/* Generate code to convert FROM to fixed point and store in TO.  FROM
5172
   must be floating point.  */
5173
 
5174
void
5175
expand_fix (rtx to, rtx from, int unsignedp)
5176
{
5177
  enum insn_code icode;
5178
  rtx target = to;
5179
  enum machine_mode fmode, imode;
5180
  int must_trunc = 0;
5181
 
5182
  /* We first try to find a pair of modes, one real and one integer, at
5183
     least as wide as FROM and TO, respectively, in which we can open-code
5184
     this conversion.  If the integer mode is wider than the mode of TO,
5185
     we can do the conversion either signed or unsigned.  */
5186
 
5187
  for (fmode = GET_MODE (from); fmode != VOIDmode;
5188
       fmode = GET_MODE_WIDER_MODE (fmode))
5189
    for (imode = GET_MODE (to); imode != VOIDmode;
5190
         imode = GET_MODE_WIDER_MODE (imode))
5191
      {
5192
        int doing_unsigned = unsignedp;
5193
 
5194
        icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5195
        if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5196
          icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5197
 
5198
        if (icode != CODE_FOR_nothing)
5199
          {
5200
            rtx last = get_last_insn ();
5201
            if (fmode != GET_MODE (from))
5202
              from = convert_to_mode (fmode, from, 0);
5203
 
5204
            if (must_trunc)
5205
              {
5206
                rtx temp = gen_reg_rtx (GET_MODE (from));
5207
                from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5208
                                    temp, 0);
5209
              }
5210
 
5211
            if (imode != GET_MODE (to))
5212
              target = gen_reg_rtx (imode);
5213
 
5214
            if (maybe_emit_unop_insn (icode, target, from,
5215
                                      doing_unsigned ? UNSIGNED_FIX : FIX))
5216
              {
5217
                if (target != to)
5218
                  convert_move (to, target, unsignedp);
5219
                return;
5220
              }
5221
            delete_insns_since (last);
5222
          }
5223
      }
5224
 
5225
  /* For an unsigned conversion, there is one more way to do it.
5226
     If we have a signed conversion, we generate code that compares
5227
     the real value to the largest representable positive number.  If if
5228
     is smaller, the conversion is done normally.  Otherwise, subtract
5229
     one plus the highest signed number, convert, and add it back.
5230
 
5231
     We only need to check all real modes, since we know we didn't find
5232
     anything with a wider integer mode.
5233
 
5234
     This code used to extend FP value into mode wider than the destination.
5235
     This is needed for decimal float modes which cannot accurately
5236
     represent one plus the highest signed number of the same size, but
5237
     not for binary modes.  Consider, for instance conversion from SFmode
5238
     into DImode.
5239
 
5240
     The hot path through the code is dealing with inputs smaller than 2^63
5241
     and doing just the conversion, so there is no bits to lose.
5242
 
5243
     In the other path we know the value is positive in the range 2^63..2^64-1
5244
     inclusive.  (as for other input overflow happens and result is undefined)
5245
     So we know that the most important bit set in mantissa corresponds to
5246
     2^63.  The subtraction of 2^63 should not generate any rounding as it
5247
     simply clears out that bit.  The rest is trivial.  */
5248
 
5249
  if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5250
    for (fmode = GET_MODE (from); fmode != VOIDmode;
5251
         fmode = GET_MODE_WIDER_MODE (fmode))
5252
      if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
5253
          && (!DECIMAL_FLOAT_MODE_P (fmode)
5254
              || GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))))
5255
        {
5256
          int bitsize;
5257
          REAL_VALUE_TYPE offset;
5258
          rtx limit, lab1, lab2, insn;
5259
 
5260
          bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5261
          real_2expN (&offset, bitsize - 1, fmode);
5262
          limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5263
          lab1 = gen_label_rtx ();
5264
          lab2 = gen_label_rtx ();
5265
 
5266
          if (fmode != GET_MODE (from))
5267
            from = convert_to_mode (fmode, from, 0);
5268
 
5269
          /* See if we need to do the subtraction.  */
5270
          do_pending_stack_adjust ();
5271
          emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5272
                                   0, lab1);
5273
 
5274
          /* If not, do the signed "fix" and branch around fixup code.  */
5275
          expand_fix (to, from, 0);
5276
          emit_jump_insn (gen_jump (lab2));
5277
          emit_barrier ();
5278
 
5279
          /* Otherwise, subtract 2**(N-1), convert to signed number,
5280
             then add 2**(N-1).  Do the addition using XOR since this
5281
             will often generate better code.  */
5282
          emit_label (lab1);
5283
          target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5284
                                 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5285
          expand_fix (to, target, 0);
5286
          target = expand_binop (GET_MODE (to), xor_optab, to,
5287
                                 gen_int_mode
5288
                                 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5289
                                  GET_MODE (to)),
5290
                                 to, 1, OPTAB_LIB_WIDEN);
5291
 
5292
          if (target != to)
5293
            emit_move_insn (to, target);
5294
 
5295
          emit_label (lab2);
5296
 
5297
          if (optab_handler (mov_optab, GET_MODE (to))->insn_code
5298
              != CODE_FOR_nothing)
5299
            {
5300
              /* Make a place for a REG_NOTE and add it.  */
5301
              insn = emit_move_insn (to, to);
5302
              set_unique_reg_note (insn,
5303
                                   REG_EQUAL,
5304
                                   gen_rtx_fmt_e (UNSIGNED_FIX,
5305
                                                  GET_MODE (to),
5306
                                                  copy_rtx (from)));
5307
            }
5308
 
5309
          return;
5310
        }
5311
 
5312
  /* We can't do it with an insn, so use a library call.  But first ensure
5313
     that the mode of TO is at least as wide as SImode, since those are the
5314
     only library calls we know about.  */
5315
 
5316
  if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5317
    {
5318
      target = gen_reg_rtx (SImode);
5319
 
5320
      expand_fix (target, from, unsignedp);
5321
    }
5322
  else
5323
    {
5324
      rtx insns;
5325
      rtx value;
5326
      rtx libfunc;
5327
 
5328
      convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5329
      libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5330
      gcc_assert (libfunc);
5331
 
5332
      start_sequence ();
5333
 
5334
      value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5335
                                       GET_MODE (to), 1, from,
5336
                                       GET_MODE (from));
5337
      insns = get_insns ();
5338
      end_sequence ();
5339
 
5340
      emit_libcall_block (insns, target, value,
5341
                          gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5342
                                         GET_MODE (to), from));
5343
    }
5344
 
5345
  if (target != to)
5346
    {
5347
      if (GET_MODE (to) == GET_MODE (target))
5348
        emit_move_insn (to, target);
5349
      else
5350
        convert_move (to, target, 0);
5351
    }
5352
}
5353
 
5354
/* Generate code to convert FROM or TO a fixed-point.
5355
   If UINTP is true, either TO or FROM is an unsigned integer.
5356
   If SATP is true, we need to saturate the result.  */
5357
 
5358
void
5359
expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5360
{
5361
  enum machine_mode to_mode = GET_MODE (to);
5362
  enum machine_mode from_mode = GET_MODE (from);
5363
  convert_optab tab;
5364
  enum rtx_code this_code;
5365
  enum insn_code code;
5366
  rtx insns, value;
5367
  rtx libfunc;
5368
 
5369
  if (to_mode == from_mode)
5370
    {
5371
      emit_move_insn (to, from);
5372
      return;
5373
    }
5374
 
5375
  if (uintp)
5376
    {
5377
      tab = satp ? satfractuns_optab : fractuns_optab;
5378
      this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5379
    }
5380
  else
5381
    {
5382
      tab = satp ? satfract_optab : fract_optab;
5383
      this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5384
    }
5385
  code = tab->handlers[to_mode][from_mode].insn_code;
5386
  if (code != CODE_FOR_nothing)
5387
    {
5388
      emit_unop_insn (code, to, from, this_code);
5389
      return;
5390
    }
5391
 
5392
  libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5393
  gcc_assert (libfunc);
5394
 
5395
  start_sequence ();
5396
  value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5397
                                   1, from, from_mode);
5398
  insns = get_insns ();
5399
  end_sequence ();
5400
 
5401
  emit_libcall_block (insns, to, value,
5402
                      gen_rtx_fmt_e (tab->code, to_mode, from));
5403
}
5404
 
5405
/* Generate code to convert FROM to fixed point and store in TO.  FROM
5406
   must be floating point, TO must be signed.  Use the conversion optab
5407
   TAB to do the conversion.  */
5408
 
5409
bool
5410
expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5411
{
5412
  enum insn_code icode;
5413
  rtx target = to;
5414
  enum machine_mode fmode, imode;
5415
 
5416
  /* We first try to find a pair of modes, one real and one integer, at
5417
     least as wide as FROM and TO, respectively, in which we can open-code
5418
     this conversion.  If the integer mode is wider than the mode of TO,
5419
     we can do the conversion either signed or unsigned.  */
5420
 
5421
  for (fmode = GET_MODE (from); fmode != VOIDmode;
5422
       fmode = GET_MODE_WIDER_MODE (fmode))
5423
    for (imode = GET_MODE (to); imode != VOIDmode;
5424
         imode = GET_MODE_WIDER_MODE (imode))
5425
      {
5426
        icode = convert_optab_handler (tab, imode, fmode)->insn_code;
5427
        if (icode != CODE_FOR_nothing)
5428
          {
5429
            rtx last = get_last_insn ();
5430
            if (fmode != GET_MODE (from))
5431
              from = convert_to_mode (fmode, from, 0);
5432
 
5433
            if (imode != GET_MODE (to))
5434
              target = gen_reg_rtx (imode);
5435
 
5436
            if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5437
              {
5438
                delete_insns_since (last);
5439
                continue;
5440
              }
5441
            if (target != to)
5442
              convert_move (to, target, 0);
5443
            return true;
5444
          }
5445
      }
5446
 
5447
  return false;
5448
}
5449
 
5450
/* Report whether we have an instruction to perform the operation
5451
   specified by CODE on operands of mode MODE.  */
5452
int
5453
have_insn_for (enum rtx_code code, enum machine_mode mode)
5454
{
5455
  return (code_to_optab[(int) code] != 0
5456
          && (optab_handler (code_to_optab[(int) code], mode)->insn_code
5457
              != CODE_FOR_nothing));
5458
}
5459
 
5460
/* Set all insn_code fields to CODE_FOR_nothing.  */
5461
 
5462
static void
5463
init_insn_codes (void)
5464
{
5465
  unsigned int i;
5466
 
5467
  for (i = 0; i < (unsigned int) OTI_MAX; i++)
5468
    {
5469
      unsigned int j;
5470
      optab op;
5471
 
5472
      op = &optab_table[i];
5473
      for (j = 0; j < NUM_MACHINE_MODES; j++)
5474
        optab_handler (op, j)->insn_code = CODE_FOR_nothing;
5475
    }
5476
  for (i = 0; i < (unsigned int) COI_MAX; i++)
5477
    {
5478
      unsigned int j, k;
5479
      convert_optab op;
5480
 
5481
      op = &convert_optab_table[i];
5482
      for (j = 0; j < NUM_MACHINE_MODES; j++)
5483
        for (k = 0; k < NUM_MACHINE_MODES; k++)
5484
          convert_optab_handler (op, j, k)->insn_code = CODE_FOR_nothing;
5485
    }
5486
}
5487
 
5488
/* Initialize OP's code to CODE, and write it into the code_to_optab table.  */
5489
static inline void
5490
init_optab (optab op, enum rtx_code code)
5491
{
5492
  op->code = code;
5493
  code_to_optab[(int) code] = op;
5494
}
5495
 
5496
/* Same, but fill in its code as CODE, and do _not_ write it into
5497
   the code_to_optab table.  */
5498
static inline void
5499
init_optabv (optab op, enum rtx_code code)
5500
{
5501
  op->code = code;
5502
}
5503
 
5504
/* Conversion optabs never go in the code_to_optab table.  */
5505
static void
5506
init_convert_optab (convert_optab op, enum rtx_code code)
5507
{
5508
  op->code = code;
5509
}
5510
 
5511
/* Initialize the libfunc fields of an entire group of entries in some
5512
   optab.  Each entry is set equal to a string consisting of a leading
5513
   pair of underscores followed by a generic operation name followed by
5514
   a mode name (downshifted to lowercase) followed by a single character
5515
   representing the number of operands for the given operation (which is
5516
   usually one of the characters '2', '3', or '4').
5517
 
5518
   OPTABLE is the table in which libfunc fields are to be initialized.
5519
   OPNAME is the generic (string) name of the operation.
5520
   SUFFIX is the character which specifies the number of operands for
5521
     the given generic operation.
5522
   MODE is the mode to generate for.
5523
*/
5524
 
5525
static void
5526
gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mode)
5527
{
5528
  unsigned opname_len = strlen (opname);
5529
  const char *mname = GET_MODE_NAME (mode);
5530
  unsigned mname_len = strlen (mname);
5531
  char *libfunc_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5532
  char *p;
5533
  const char *q;
5534
 
5535
  p = libfunc_name;
5536
  *p++ = '_';
5537
  *p++ = '_';
5538
  for (q = opname; *q; )
5539
    *p++ = *q++;
5540
  for (q = mname; *q; q++)
5541
    *p++ = TOLOWER (*q);
5542
  *p++ = suffix;
5543
  *p = '\0';
5544
 
5545
  set_optab_libfunc (optable, mode,
5546
                     ggc_alloc_string (libfunc_name, p - libfunc_name));
5547
}
5548
 
5549
/* Like gen_libfunc, but verify that integer operation is involved.  */
5550
 
5551
static void
5552
gen_int_libfunc (optab optable, const char *opname, char suffix,
5553
                 enum machine_mode mode)
5554
{
5555
  int maxsize = 2 * BITS_PER_WORD;
5556
 
5557
  if (GET_MODE_CLASS (mode) != MODE_INT)
5558
    return;
5559
  if (maxsize < LONG_LONG_TYPE_SIZE)
5560
    maxsize = LONG_LONG_TYPE_SIZE;
5561
  if (GET_MODE_CLASS (mode) != MODE_INT
5562
      || mode < word_mode || GET_MODE_BITSIZE (mode) > maxsize)
5563
    return;
5564
  gen_libfunc (optable, opname, suffix, mode);
5565
}
5566
 
5567
/* Like gen_libfunc, but verify that FP and set decimal prefix if needed.  */
5568
 
5569
static void
5570
gen_fp_libfunc (optab optable, const char *opname, char suffix,
5571
                enum machine_mode mode)
5572
{
5573
  char *dec_opname;
5574
 
5575
  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5576
    gen_libfunc (optable, opname, suffix, mode);
5577
  if (DECIMAL_FLOAT_MODE_P (mode))
5578
    {
5579
      dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
5580
      /* For BID support, change the name to have either a bid_ or dpd_ prefix
5581
         depending on the low level floating format used.  */
5582
      memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5583
      strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5584
      gen_libfunc (optable, dec_opname, suffix, mode);
5585
    }
5586
}
5587
 
5588
/* Like gen_libfunc, but verify that fixed-point operation is involved.  */
5589
 
5590
static void
5591
gen_fixed_libfunc (optab optable, const char *opname, char suffix,
5592
                   enum machine_mode mode)
5593
{
5594
  if (!ALL_FIXED_POINT_MODE_P (mode))
5595
    return;
5596
  gen_libfunc (optable, opname, suffix, mode);
5597
}
5598
 
5599
/* Like gen_libfunc, but verify that signed fixed-point operation is
5600
   involved.  */
5601
 
5602
static void
5603
gen_signed_fixed_libfunc (optab optable, const char *opname, char suffix,
5604
                          enum machine_mode mode)
5605
{
5606
  if (!SIGNED_FIXED_POINT_MODE_P (mode))
5607
    return;
5608
  gen_libfunc (optable, opname, suffix, mode);
5609
}
5610
 
5611
/* Like gen_libfunc, but verify that unsigned fixed-point operation is
5612
   involved.  */
5613
 
5614
static void
5615
gen_unsigned_fixed_libfunc (optab optable, const char *opname, char suffix,
5616
                            enum machine_mode mode)
5617
{
5618
  if (!UNSIGNED_FIXED_POINT_MODE_P (mode))
5619
    return;
5620
  gen_libfunc (optable, opname, suffix, mode);
5621
}
5622
 
5623
/* Like gen_libfunc, but verify that FP or INT operation is involved.  */
5624
 
5625
static void
5626
gen_int_fp_libfunc (optab optable, const char *name, char suffix,
5627
                    enum machine_mode mode)
5628
{
5629
  if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5630
    gen_fp_libfunc (optable, name, suffix, mode);
5631
  if (INTEGRAL_MODE_P (mode))
5632
    gen_int_libfunc (optable, name, suffix, mode);
5633
}
5634
 
5635
/* Like gen_libfunc, but verify that FP or INT operation is involved
5636
   and add 'v' suffix for integer operation.  */
5637
 
5638
static void
5639
gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
5640
                     enum machine_mode mode)
5641
{
5642
  if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5643
    gen_fp_libfunc (optable, name, suffix, mode);
5644
  if (GET_MODE_CLASS (mode) == MODE_INT)
5645
    {
5646
      int len = strlen (name);
5647
      char *v_name = XALLOCAVEC (char, len + 2);
5648
      strcpy (v_name, name);
5649
      v_name[len] = 'v';
5650
      v_name[len + 1] = 0;
5651
      gen_int_libfunc (optable, v_name, suffix, mode);
5652
    }
5653
}
5654
 
5655
/* Like gen_libfunc, but verify that FP or INT or FIXED operation is
5656
   involved.  */
5657
 
5658
static void
5659
gen_int_fp_fixed_libfunc (optab optable, const char *name, char suffix,
5660
                          enum machine_mode mode)
5661
{
5662
  if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5663
    gen_fp_libfunc (optable, name, suffix, mode);
5664
  if (INTEGRAL_MODE_P (mode))
5665
    gen_int_libfunc (optable, name, suffix, mode);
5666
  if (ALL_FIXED_POINT_MODE_P (mode))
5667
    gen_fixed_libfunc (optable, name, suffix, mode);
5668
}
5669
 
5670
/* Like gen_libfunc, but verify that FP or INT or signed FIXED operation is
5671
   involved.  */
5672
 
5673
static void
5674
gen_int_fp_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5675
                                 enum machine_mode mode)
5676
{
5677
  if (DECIMAL_FLOAT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_FLOAT)
5678
    gen_fp_libfunc (optable, name, suffix, mode);
5679
  if (INTEGRAL_MODE_P (mode))
5680
    gen_int_libfunc (optable, name, suffix, mode);
5681
  if (SIGNED_FIXED_POINT_MODE_P (mode))
5682
    gen_signed_fixed_libfunc (optable, name, suffix, mode);
5683
}
5684
 
5685
/* Like gen_libfunc, but verify that INT or FIXED operation is
5686
   involved.  */
5687
 
5688
static void
5689
gen_int_fixed_libfunc (optab optable, const char *name, char suffix,
5690
                       enum machine_mode mode)
5691
{
5692
  if (INTEGRAL_MODE_P (mode))
5693
    gen_int_libfunc (optable, name, suffix, mode);
5694
  if (ALL_FIXED_POINT_MODE_P (mode))
5695
    gen_fixed_libfunc (optable, name, suffix, mode);
5696
}
5697
 
5698
/* Like gen_libfunc, but verify that INT or signed FIXED operation is
5699
   involved.  */
5700
 
5701
static void
5702
gen_int_signed_fixed_libfunc (optab optable, const char *name, char suffix,
5703
                              enum machine_mode mode)
5704
{
5705
  if (INTEGRAL_MODE_P (mode))
5706
    gen_int_libfunc (optable, name, suffix, mode);
5707
  if (SIGNED_FIXED_POINT_MODE_P (mode))
5708
    gen_signed_fixed_libfunc (optable, name, suffix, mode);
5709
}
5710
 
5711
/* Like gen_libfunc, but verify that INT or unsigned FIXED operation is
5712
   involved.  */
5713
 
5714
static void
5715
gen_int_unsigned_fixed_libfunc (optab optable, const char *name, char suffix,
5716
                                enum machine_mode mode)
5717
{
5718
  if (INTEGRAL_MODE_P (mode))
5719
    gen_int_libfunc (optable, name, suffix, mode);
5720
  if (UNSIGNED_FIXED_POINT_MODE_P (mode))
5721
    gen_unsigned_fixed_libfunc (optable, name, suffix, mode);
5722
}
5723
 
5724
/* Initialize the libfunc fields of an entire group of entries of an
5725
   inter-mode-class conversion optab.  The string formation rules are
5726
   similar to the ones for init_libfuncs, above, but instead of having
5727
   a mode name and an operand count these functions have two mode names
5728
   and no operand count.  */
5729
 
5730
static void
5731
gen_interclass_conv_libfunc (convert_optab tab,
5732
                             const char *opname,
5733
                             enum machine_mode tmode,
5734
                             enum machine_mode fmode)
5735
{
5736
  size_t opname_len = strlen (opname);
5737
  size_t mname_len = 0;
5738
 
5739
  const char *fname, *tname;
5740
  const char *q;
5741
  char *libfunc_name, *suffix;
5742
  char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5743
  char *p;
5744
 
5745
  /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5746
     depends on which underlying decimal floating point format is used.  */
5747
  const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5748
 
5749
  mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5750
 
5751
  nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5752
  nondec_name[0] = '_';
5753
  nondec_name[1] = '_';
5754
  memcpy (&nondec_name[2], opname, opname_len);
5755
  nondec_suffix = nondec_name + opname_len + 2;
5756
 
5757
  dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5758
  dec_name[0] = '_';
5759
  dec_name[1] = '_';
5760
  memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5761
  memcpy (&dec_name[2+dec_len], opname, opname_len);
5762
  dec_suffix = dec_name + dec_len + opname_len + 2;
5763
 
5764
  fname = GET_MODE_NAME (fmode);
5765
  tname = GET_MODE_NAME (tmode);
5766
 
5767
  if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5768
    {
5769
      libfunc_name = dec_name;
5770
      suffix = dec_suffix;
5771
    }
5772
  else
5773
    {
5774
      libfunc_name = nondec_name;
5775
      suffix = nondec_suffix;
5776
    }
5777
 
5778
  p = suffix;
5779
  for (q = fname; *q; p++, q++)
5780
    *p = TOLOWER (*q);
5781
  for (q = tname; *q; p++, q++)
5782
    *p = TOLOWER (*q);
5783
 
5784
  *p = '\0';
5785
 
5786
  set_conv_libfunc (tab, tmode, fmode,
5787
                    ggc_alloc_string (libfunc_name, p - libfunc_name));
5788
}
5789
 
5790
/* Same as gen_interclass_conv_libfunc but verify that we are producing
5791
   int->fp conversion.  */
5792
 
5793
static void
5794
gen_int_to_fp_conv_libfunc (convert_optab tab,
5795
                            const char *opname,
5796
                            enum machine_mode tmode,
5797
                            enum machine_mode fmode)
5798
{
5799
  if (GET_MODE_CLASS (fmode) != MODE_INT)
5800
    return;
5801
  if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5802
    return;
5803
  gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5804
}
5805
 
5806
/* ufloat_optab is special by using floatun for FP and floatuns decimal fp
5807
   naming scheme.  */
5808
 
5809
static void
5810
gen_ufloat_conv_libfunc (convert_optab tab,
5811
                         const char *opname ATTRIBUTE_UNUSED,
5812
                         enum machine_mode tmode,
5813
                         enum machine_mode fmode)
5814
{
5815
  if (DECIMAL_FLOAT_MODE_P (tmode))
5816
    gen_int_to_fp_conv_libfunc (tab, "floatuns", tmode, fmode);
5817
  else
5818
    gen_int_to_fp_conv_libfunc (tab, "floatun", tmode, fmode);
5819
}
5820
 
5821
/* Same as gen_interclass_conv_libfunc but verify that we are producing
5822
   fp->int conversion.  */
5823
 
5824
static void
5825
gen_int_to_fp_nondecimal_conv_libfunc (convert_optab tab,
5826
                                       const char *opname,
5827
                                       enum machine_mode tmode,
5828
                                       enum machine_mode fmode)
5829
{
5830
  if (GET_MODE_CLASS (fmode) != MODE_INT)
5831
    return;
5832
  if (GET_MODE_CLASS (tmode) != MODE_FLOAT)
5833
    return;
5834
  gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5835
}
5836
 
5837
/* Same as gen_interclass_conv_libfunc but verify that we are producing
5838
   fp->int conversion with no decimal floating point involved.  */
5839
 
5840
static void
5841
gen_fp_to_int_conv_libfunc (convert_optab tab,
5842
                            const char *opname,
5843
                            enum machine_mode tmode,
5844
                            enum machine_mode fmode)
5845
{
5846
  if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5847
    return;
5848
  if (GET_MODE_CLASS (tmode) != MODE_INT)
5849
    return;
5850
  gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5851
}
5852
 
5853
/* Initialize the libfunc fields of an of an intra-mode-class conversion optab.
5854
   The string formation rules are
5855
   similar to the ones for init_libfunc, above.  */
5856
 
5857
static void
5858
gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
5859
                             enum machine_mode tmode, enum machine_mode fmode)
5860
{
5861
  size_t opname_len = strlen (opname);
5862
  size_t mname_len = 0;
5863
 
5864
  const char *fname, *tname;
5865
  const char *q;
5866
  char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5867
  char *libfunc_name, *suffix;
5868
  char *p;
5869
 
5870
  /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5871
     depends on which underlying decimal floating point format is used.  */
5872
  const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5873
 
5874
  mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
5875
 
5876
  nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
5877
  nondec_name[0] = '_';
5878
  nondec_name[1] = '_';
5879
  memcpy (&nondec_name[2], opname, opname_len);
5880
  nondec_suffix = nondec_name + opname_len + 2;
5881
 
5882
  dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
5883
  dec_name[0] = '_';
5884
  dec_name[1] = '_';
5885
  memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5886
  memcpy (&dec_name[2 + dec_len], opname, opname_len);
5887
  dec_suffix = dec_name + dec_len + opname_len + 2;
5888
 
5889
  fname = GET_MODE_NAME (fmode);
5890
  tname = GET_MODE_NAME (tmode);
5891
 
5892
  if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5893
    {
5894
      libfunc_name = dec_name;
5895
      suffix = dec_suffix;
5896
    }
5897
  else
5898
    {
5899
      libfunc_name = nondec_name;
5900
      suffix = nondec_suffix;
5901
    }
5902
 
5903
  p = suffix;
5904
  for (q = fname; *q; p++, q++)
5905
    *p = TOLOWER (*q);
5906
  for (q = tname; *q; p++, q++)
5907
    *p = TOLOWER (*q);
5908
 
5909
  *p++ = '2';
5910
  *p = '\0';
5911
 
5912
  set_conv_libfunc (tab, tmode, fmode,
5913
                    ggc_alloc_string (libfunc_name, p - libfunc_name));
5914
}
5915
 
5916
/* Pick proper libcall for trunc_optab.  We need to chose if we do
5917
   truncation or extension and interclass or intraclass.  */
5918
 
5919
static void
5920
gen_trunc_conv_libfunc (convert_optab tab,
5921
                         const char *opname,
5922
                         enum machine_mode tmode,
5923
                         enum machine_mode fmode)
5924
{
5925
  if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5926
    return;
5927
  if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5928
    return;
5929
  if (tmode == fmode)
5930
    return;
5931
 
5932
  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5933
      || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5934
     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5935
 
5936
  if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
5937
    return;
5938
 
5939
  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5940
       && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5941
      || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5942
    gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5943
}
5944
 
5945
/* Pick proper libcall for extend_optab.  We need to chose if we do
5946
   truncation or extension and interclass or intraclass.  */
5947
 
5948
static void
5949
gen_extend_conv_libfunc (convert_optab tab,
5950
                         const char *opname ATTRIBUTE_UNUSED,
5951
                         enum machine_mode tmode,
5952
                         enum machine_mode fmode)
5953
{
5954
  if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
5955
    return;
5956
  if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
5957
    return;
5958
  if (tmode == fmode)
5959
    return;
5960
 
5961
  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
5962
      || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode)))
5963
     gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5964
 
5965
  if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
5966
    return;
5967
 
5968
  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
5969
       && GET_MODE_CLASS (fmode) == MODE_FLOAT)
5970
      || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
5971
    gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5972
}
5973
 
5974
/* Pick proper libcall for fract_optab.  We need to chose if we do
5975
   interclass or intraclass.  */
5976
 
5977
static void
5978
gen_fract_conv_libfunc (convert_optab tab,
5979
                        const char *opname,
5980
                        enum machine_mode tmode,
5981
                        enum machine_mode fmode)
5982
{
5983
  if (tmode == fmode)
5984
    return;
5985
  if (!(ALL_FIXED_POINT_MODE_P (tmode) || ALL_FIXED_POINT_MODE_P (fmode)))
5986
    return;
5987
 
5988
  if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
5989
    gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
5990
  else
5991
    gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
5992
}
5993
 
5994
/* Pick proper libcall for fractuns_optab.  */
5995
 
5996
static void
5997
gen_fractuns_conv_libfunc (convert_optab tab,
5998
                           const char *opname,
5999
                           enum machine_mode tmode,
6000
                           enum machine_mode fmode)
6001
{
6002
  if (tmode == fmode)
6003
    return;
6004
  /* One mode must be a fixed-point mode, and the other must be an integer
6005
     mode. */
6006
  if (!((ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT)
6007
        || (ALL_FIXED_POINT_MODE_P (fmode)
6008
            && GET_MODE_CLASS (tmode) == MODE_INT)))
6009
    return;
6010
 
6011
  gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6012
}
6013
 
6014
/* Pick proper libcall for satfract_optab.  We need to chose if we do
6015
   interclass or intraclass.  */
6016
 
6017
static void
6018
gen_satfract_conv_libfunc (convert_optab tab,
6019
                           const char *opname,
6020
                           enum machine_mode tmode,
6021
                           enum machine_mode fmode)
6022
{
6023
  if (tmode == fmode)
6024
    return;
6025
  /* TMODE must be a fixed-point mode.  */
6026
  if (!ALL_FIXED_POINT_MODE_P (tmode))
6027
    return;
6028
 
6029
  if (GET_MODE_CLASS (tmode) == GET_MODE_CLASS (fmode))
6030
    gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
6031
  else
6032
    gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6033
}
6034
 
6035
/* Pick proper libcall for satfractuns_optab.  */
6036
 
6037
static void
6038
gen_satfractuns_conv_libfunc (convert_optab tab,
6039
                              const char *opname,
6040
                              enum machine_mode tmode,
6041
                              enum machine_mode fmode)
6042
{
6043
  if (tmode == fmode)
6044
    return;
6045
  /* TMODE must be a fixed-point mode, and FMODE must be an integer mode. */
6046
  if (!(ALL_FIXED_POINT_MODE_P (tmode) && GET_MODE_CLASS (fmode) == MODE_INT))
6047
    return;
6048
 
6049
  gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
6050
}
6051
 
6052
/* A table of previously-created libfuncs, hashed by name.  */
6053
static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
6054
 
6055
/* Hashtable callbacks for libfunc_decls.  */
6056
 
6057
static hashval_t
6058
libfunc_decl_hash (const void *entry)
6059
{
6060
  return htab_hash_string (IDENTIFIER_POINTER (DECL_NAME ((const_tree) entry)));
6061
}
6062
 
6063
static int
6064
libfunc_decl_eq (const void *entry1, const void *entry2)
6065
{
6066
  return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
6067
}
6068
 
6069
/* Build a decl for a libfunc named NAME. */
6070
 
6071
tree
6072
build_libfunc_function (const char *name)
6073
{
6074
  tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
6075
                          get_identifier (name),
6076
                          build_function_type (integer_type_node, NULL_TREE));
6077
  /* ??? We don't have any type information except for this is
6078
     a function.  Pretend this is "int foo()".  */
6079
  DECL_ARTIFICIAL (decl) = 1;
6080
  DECL_EXTERNAL (decl) = 1;
6081
  TREE_PUBLIC (decl) = 1;
6082
  gcc_assert (DECL_ASSEMBLER_NAME (decl));
6083
 
6084
  /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
6085
     are the flags assigned by targetm.encode_section_info.  */
6086
  SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
6087
 
6088
  return decl;
6089
}
6090
 
6091
rtx
6092
init_one_libfunc (const char *name)
6093
{
6094
  tree id, decl;
6095
  void **slot;
6096
  hashval_t hash;
6097
 
6098
  if (libfunc_decls == NULL)
6099
    libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
6100
                                     libfunc_decl_eq, NULL);
6101
 
6102
  /* See if we have already created a libfunc decl for this function.  */
6103
  id = get_identifier (name);
6104
  hash = htab_hash_string (name);
6105
  slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
6106
  decl = (tree) *slot;
6107
  if (decl == NULL)
6108
    {
6109
      /* Create a new decl, so that it can be passed to
6110
         targetm.encode_section_info.  */
6111
      decl = build_libfunc_function (name);
6112
      *slot = decl;
6113
    }
6114
  return XEXP (DECL_RTL (decl), 0);
6115
}
6116
 
6117
/* Adjust the assembler name of libfunc NAME to ASMSPEC.  */
6118
 
6119
rtx
6120
set_user_assembler_libfunc (const char *name, const char *asmspec)
6121
{
6122
  tree id, decl;
6123
  void **slot;
6124
  hashval_t hash;
6125
 
6126
  id = get_identifier (name);
6127
  hash = htab_hash_string (name);
6128
  slot = htab_find_slot_with_hash (libfunc_decls, id, hash, NO_INSERT);
6129
  gcc_assert (slot);
6130
  decl = (tree) *slot;
6131
  set_user_assembler_name (decl, asmspec);
6132
  return XEXP (DECL_RTL (decl), 0);
6133
}
6134
 
6135
/* Call this to reset the function entry for one optab (OPTABLE) in mode
6136
   MODE to NAME, which should be either 0 or a string constant.  */
6137
void
6138
set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
6139
{
6140
  rtx val;
6141
  struct libfunc_entry e;
6142
  struct libfunc_entry **slot;
6143
  e.optab = (size_t) (optable - &optab_table[0]);
6144
  e.mode1 = mode;
6145
  e.mode2 = VOIDmode;
6146
 
6147
  if (name)
6148
    val = init_one_libfunc (name);
6149
  else
6150
    val = 0;
6151
  slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6152
  if (*slot == NULL)
6153
    *slot = GGC_NEW (struct libfunc_entry);
6154
  (*slot)->optab = (size_t) (optable - &optab_table[0]);
6155
  (*slot)->mode1 = mode;
6156
  (*slot)->mode2 = VOIDmode;
6157
  (*slot)->libfunc = val;
6158
}
6159
 
6160
/* Call this to reset the function entry for one conversion optab
6161
   (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
6162
   either 0 or a string constant.  */
6163
void
6164
set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
6165
                  enum machine_mode fmode, const char *name)
6166
{
6167
  rtx val;
6168
  struct libfunc_entry e;
6169
  struct libfunc_entry **slot;
6170
  e.optab = (size_t) (optable - &convert_optab_table[0]);
6171
  e.mode1 = tmode;
6172
  e.mode2 = fmode;
6173
 
6174
  if (name)
6175
    val = init_one_libfunc (name);
6176
  else
6177
    val = 0;
6178
  slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
6179
  if (*slot == NULL)
6180
    *slot = GGC_NEW (struct libfunc_entry);
6181
  (*slot)->optab = (size_t) (optable - &convert_optab_table[0]);
6182
  (*slot)->mode1 = tmode;
6183
  (*slot)->mode2 = fmode;
6184
  (*slot)->libfunc = val;
6185
}
6186
 
6187
/* Call this to initialize the contents of the optabs
6188
   appropriately for the current target machine.  */
6189
 
6190
void
6191
init_optabs (void)
6192
{
6193
  unsigned int i;
6194
  static bool reinit;
6195
 
6196
  libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
6197
  /* Start by initializing all tables to contain CODE_FOR_nothing.  */
6198
 
6199
#ifdef HAVE_conditional_move
6200
  for (i = 0; i < NUM_MACHINE_MODES; i++)
6201
    movcc_gen_code[i] = CODE_FOR_nothing;
6202
#endif
6203
 
6204
  for (i = 0; i < NUM_MACHINE_MODES; i++)
6205
    {
6206
      vcond_gen_code[i] = CODE_FOR_nothing;
6207
      vcondu_gen_code[i] = CODE_FOR_nothing;
6208
    }
6209
 
6210
#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
6211
  /* We statically initialize the insn_codes with CODE_FOR_nothing.  */
6212
  if (reinit)
6213
    init_insn_codes ();
6214
#else
6215
  init_insn_codes ();
6216
#endif
6217
 
6218
  init_optab (add_optab, PLUS);
6219
  init_optabv (addv_optab, PLUS);
6220
  init_optab (sub_optab, MINUS);
6221
  init_optabv (subv_optab, MINUS);
6222
  init_optab (ssadd_optab, SS_PLUS);
6223
  init_optab (usadd_optab, US_PLUS);
6224
  init_optab (sssub_optab, SS_MINUS);
6225
  init_optab (ussub_optab, US_MINUS);
6226
  init_optab (smul_optab, MULT);
6227
  init_optab (ssmul_optab, SS_MULT);
6228
  init_optab (usmul_optab, US_MULT);
6229
  init_optabv (smulv_optab, MULT);
6230
  init_optab (smul_highpart_optab, UNKNOWN);
6231
  init_optab (umul_highpart_optab, UNKNOWN);
6232
  init_optab (smul_widen_optab, UNKNOWN);
6233
  init_optab (umul_widen_optab, UNKNOWN);
6234
  init_optab (usmul_widen_optab, UNKNOWN);
6235
  init_optab (smadd_widen_optab, UNKNOWN);
6236
  init_optab (umadd_widen_optab, UNKNOWN);
6237
  init_optab (ssmadd_widen_optab, UNKNOWN);
6238
  init_optab (usmadd_widen_optab, UNKNOWN);
6239
  init_optab (smsub_widen_optab, UNKNOWN);
6240
  init_optab (umsub_widen_optab, UNKNOWN);
6241
  init_optab (ssmsub_widen_optab, UNKNOWN);
6242
  init_optab (usmsub_widen_optab, UNKNOWN);
6243
  init_optab (sdiv_optab, DIV);
6244
  init_optab (ssdiv_optab, SS_DIV);
6245
  init_optab (usdiv_optab, US_DIV);
6246
  init_optabv (sdivv_optab, DIV);
6247
  init_optab (sdivmod_optab, UNKNOWN);
6248
  init_optab (udiv_optab, UDIV);
6249
  init_optab (udivmod_optab, UNKNOWN);
6250
  init_optab (smod_optab, MOD);
6251
  init_optab (umod_optab, UMOD);
6252
  init_optab (fmod_optab, UNKNOWN);
6253
  init_optab (remainder_optab, UNKNOWN);
6254
  init_optab (ftrunc_optab, UNKNOWN);
6255
  init_optab (and_optab, AND);
6256
  init_optab (ior_optab, IOR);
6257
  init_optab (xor_optab, XOR);
6258
  init_optab (ashl_optab, ASHIFT);
6259
  init_optab (ssashl_optab, SS_ASHIFT);
6260
  init_optab (usashl_optab, US_ASHIFT);
6261
  init_optab (ashr_optab, ASHIFTRT);
6262
  init_optab (lshr_optab, LSHIFTRT);
6263
  init_optab (rotl_optab, ROTATE);
6264
  init_optab (rotr_optab, ROTATERT);
6265
  init_optab (smin_optab, SMIN);
6266
  init_optab (smax_optab, SMAX);
6267
  init_optab (umin_optab, UMIN);
6268
  init_optab (umax_optab, UMAX);
6269
  init_optab (pow_optab, UNKNOWN);
6270
  init_optab (atan2_optab, UNKNOWN);
6271
 
6272
  /* These three have codes assigned exclusively for the sake of
6273
     have_insn_for.  */
6274
  init_optab (mov_optab, SET);
6275
  init_optab (movstrict_optab, STRICT_LOW_PART);
6276
  init_optab (cbranch_optab, COMPARE);
6277
 
6278
  init_optab (cmov_optab, UNKNOWN);
6279
  init_optab (cstore_optab, UNKNOWN);
6280
  init_optab (ctrap_optab, UNKNOWN);
6281
 
6282
  init_optab (storent_optab, UNKNOWN);
6283
 
6284
  init_optab (cmp_optab, UNKNOWN);
6285
  init_optab (ucmp_optab, UNKNOWN);
6286
 
6287
  init_optab (eq_optab, EQ);
6288
  init_optab (ne_optab, NE);
6289
  init_optab (gt_optab, GT);
6290
  init_optab (ge_optab, GE);
6291
  init_optab (lt_optab, LT);
6292
  init_optab (le_optab, LE);
6293
  init_optab (unord_optab, UNORDERED);
6294
 
6295
  init_optab (neg_optab, NEG);
6296
  init_optab (ssneg_optab, SS_NEG);
6297
  init_optab (usneg_optab, US_NEG);
6298
  init_optabv (negv_optab, NEG);
6299
  init_optab (abs_optab, ABS);
6300
  init_optabv (absv_optab, ABS);
6301
  init_optab (addcc_optab, UNKNOWN);
6302
  init_optab (one_cmpl_optab, NOT);
6303
  init_optab (bswap_optab, BSWAP);
6304
  init_optab (ffs_optab, FFS);
6305
  init_optab (clz_optab, CLZ);
6306
  init_optab (ctz_optab, CTZ);
6307
  init_optab (popcount_optab, POPCOUNT);
6308
  init_optab (parity_optab, PARITY);
6309
  init_optab (sqrt_optab, SQRT);
6310
  init_optab (floor_optab, UNKNOWN);
6311
  init_optab (ceil_optab, UNKNOWN);
6312
  init_optab (round_optab, UNKNOWN);
6313
  init_optab (btrunc_optab, UNKNOWN);
6314
  init_optab (nearbyint_optab, UNKNOWN);
6315
  init_optab (rint_optab, UNKNOWN);
6316
  init_optab (sincos_optab, UNKNOWN);
6317
  init_optab (sin_optab, UNKNOWN);
6318
  init_optab (asin_optab, UNKNOWN);
6319
  init_optab (cos_optab, UNKNOWN);
6320
  init_optab (acos_optab, UNKNOWN);
6321
  init_optab (exp_optab, UNKNOWN);
6322
  init_optab (exp10_optab, UNKNOWN);
6323
  init_optab (exp2_optab, UNKNOWN);
6324
  init_optab (expm1_optab, UNKNOWN);
6325
  init_optab (ldexp_optab, UNKNOWN);
6326
  init_optab (scalb_optab, UNKNOWN);
6327
  init_optab (significand_optab, UNKNOWN);
6328
  init_optab (logb_optab, UNKNOWN);
6329
  init_optab (ilogb_optab, UNKNOWN);
6330
  init_optab (log_optab, UNKNOWN);
6331
  init_optab (log10_optab, UNKNOWN);
6332
  init_optab (log2_optab, UNKNOWN);
6333
  init_optab (log1p_optab, UNKNOWN);
6334
  init_optab (tan_optab, UNKNOWN);
6335
  init_optab (atan_optab, UNKNOWN);
6336
  init_optab (copysign_optab, UNKNOWN);
6337
  init_optab (signbit_optab, UNKNOWN);
6338
 
6339
  init_optab (isinf_optab, UNKNOWN);
6340
 
6341
  init_optab (strlen_optab, UNKNOWN);
6342
  init_optab (push_optab, UNKNOWN);
6343
 
6344
  init_optab (reduc_smax_optab, UNKNOWN);
6345
  init_optab (reduc_umax_optab, UNKNOWN);
6346
  init_optab (reduc_smin_optab, UNKNOWN);
6347
  init_optab (reduc_umin_optab, UNKNOWN);
6348
  init_optab (reduc_splus_optab, UNKNOWN);
6349
  init_optab (reduc_uplus_optab, UNKNOWN);
6350
 
6351
  init_optab (ssum_widen_optab, UNKNOWN);
6352
  init_optab (usum_widen_optab, UNKNOWN);
6353
  init_optab (sdot_prod_optab, UNKNOWN);
6354
  init_optab (udot_prod_optab, UNKNOWN);
6355
 
6356
  init_optab (vec_extract_optab, UNKNOWN);
6357
  init_optab (vec_extract_even_optab, UNKNOWN);
6358
  init_optab (vec_extract_odd_optab, UNKNOWN);
6359
  init_optab (vec_interleave_high_optab, UNKNOWN);
6360
  init_optab (vec_interleave_low_optab, UNKNOWN);
6361
  init_optab (vec_set_optab, UNKNOWN);
6362
  init_optab (vec_init_optab, UNKNOWN);
6363
  init_optab (vec_shl_optab, UNKNOWN);
6364
  init_optab (vec_shr_optab, UNKNOWN);
6365
  init_optab (vec_realign_load_optab, UNKNOWN);
6366
  init_optab (movmisalign_optab, UNKNOWN);
6367
  init_optab (vec_widen_umult_hi_optab, UNKNOWN);
6368
  init_optab (vec_widen_umult_lo_optab, UNKNOWN);
6369
  init_optab (vec_widen_smult_hi_optab, UNKNOWN);
6370
  init_optab (vec_widen_smult_lo_optab, UNKNOWN);
6371
  init_optab (vec_unpacks_hi_optab, UNKNOWN);
6372
  init_optab (vec_unpacks_lo_optab, UNKNOWN);
6373
  init_optab (vec_unpacku_hi_optab, UNKNOWN);
6374
  init_optab (vec_unpacku_lo_optab, UNKNOWN);
6375
  init_optab (vec_unpacks_float_hi_optab, UNKNOWN);
6376
  init_optab (vec_unpacks_float_lo_optab, UNKNOWN);
6377
  init_optab (vec_unpacku_float_hi_optab, UNKNOWN);
6378
  init_optab (vec_unpacku_float_lo_optab, UNKNOWN);
6379
  init_optab (vec_pack_trunc_optab, UNKNOWN);
6380
  init_optab (vec_pack_usat_optab, UNKNOWN);
6381
  init_optab (vec_pack_ssat_optab, UNKNOWN);
6382
  init_optab (vec_pack_ufix_trunc_optab, UNKNOWN);
6383
  init_optab (vec_pack_sfix_trunc_optab, UNKNOWN);
6384
 
6385
  init_optab (powi_optab, UNKNOWN);
6386
 
6387
  /* Conversions.  */
6388
  init_convert_optab (sext_optab, SIGN_EXTEND);
6389
  init_convert_optab (zext_optab, ZERO_EXTEND);
6390
  init_convert_optab (trunc_optab, TRUNCATE);
6391
  init_convert_optab (sfix_optab, FIX);
6392
  init_convert_optab (ufix_optab, UNSIGNED_FIX);
6393
  init_convert_optab (sfixtrunc_optab, UNKNOWN);
6394
  init_convert_optab (ufixtrunc_optab, UNKNOWN);
6395
  init_convert_optab (sfloat_optab, FLOAT);
6396
  init_convert_optab (ufloat_optab, UNSIGNED_FLOAT);
6397
  init_convert_optab (lrint_optab, UNKNOWN);
6398
  init_convert_optab (lround_optab, UNKNOWN);
6399
  init_convert_optab (lfloor_optab, UNKNOWN);
6400
  init_convert_optab (lceil_optab, UNKNOWN);
6401
 
6402
  init_convert_optab (fract_optab, FRACT_CONVERT);
6403
  init_convert_optab (fractuns_optab, UNSIGNED_FRACT_CONVERT);
6404
  init_convert_optab (satfract_optab, SAT_FRACT);
6405
  init_convert_optab (satfractuns_optab, UNSIGNED_SAT_FRACT);
6406
 
6407
  for (i = 0; i < NUM_MACHINE_MODES; i++)
6408
    {
6409
      movmem_optab[i] = CODE_FOR_nothing;
6410
      cmpstr_optab[i] = CODE_FOR_nothing;
6411
      cmpstrn_optab[i] = CODE_FOR_nothing;
6412
      cmpmem_optab[i] = CODE_FOR_nothing;
6413
      setmem_optab[i] = CODE_FOR_nothing;
6414
 
6415
      sync_add_optab[i] = CODE_FOR_nothing;
6416
      sync_sub_optab[i] = CODE_FOR_nothing;
6417
      sync_ior_optab[i] = CODE_FOR_nothing;
6418
      sync_and_optab[i] = CODE_FOR_nothing;
6419
      sync_xor_optab[i] = CODE_FOR_nothing;
6420
      sync_nand_optab[i] = CODE_FOR_nothing;
6421
      sync_old_add_optab[i] = CODE_FOR_nothing;
6422
      sync_old_sub_optab[i] = CODE_FOR_nothing;
6423
      sync_old_ior_optab[i] = CODE_FOR_nothing;
6424
      sync_old_and_optab[i] = CODE_FOR_nothing;
6425
      sync_old_xor_optab[i] = CODE_FOR_nothing;
6426
      sync_old_nand_optab[i] = CODE_FOR_nothing;
6427
      sync_new_add_optab[i] = CODE_FOR_nothing;
6428
      sync_new_sub_optab[i] = CODE_FOR_nothing;
6429
      sync_new_ior_optab[i] = CODE_FOR_nothing;
6430
      sync_new_and_optab[i] = CODE_FOR_nothing;
6431
      sync_new_xor_optab[i] = CODE_FOR_nothing;
6432
      sync_new_nand_optab[i] = CODE_FOR_nothing;
6433
      sync_compare_and_swap[i] = CODE_FOR_nothing;
6434
      sync_lock_test_and_set[i] = CODE_FOR_nothing;
6435
      sync_lock_release[i] = CODE_FOR_nothing;
6436
 
6437
      reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
6438
    }
6439
 
6440
  /* Fill in the optabs with the insns we support.  */
6441
  init_all_optabs ();
6442
 
6443
  /* Initialize the optabs with the names of the library functions.  */
6444
  add_optab->libcall_basename = "add";
6445
  add_optab->libcall_suffix = '3';
6446
  add_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6447
  addv_optab->libcall_basename = "add";
6448
  addv_optab->libcall_suffix = '3';
6449
  addv_optab->libcall_gen = gen_intv_fp_libfunc;
6450
  ssadd_optab->libcall_basename = "ssadd";
6451
  ssadd_optab->libcall_suffix = '3';
6452
  ssadd_optab->libcall_gen = gen_signed_fixed_libfunc;
6453
  usadd_optab->libcall_basename = "usadd";
6454
  usadd_optab->libcall_suffix = '3';
6455
  usadd_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6456
  sub_optab->libcall_basename = "sub";
6457
  sub_optab->libcall_suffix = '3';
6458
  sub_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6459
  subv_optab->libcall_basename = "sub";
6460
  subv_optab->libcall_suffix = '3';
6461
  subv_optab->libcall_gen = gen_intv_fp_libfunc;
6462
  sssub_optab->libcall_basename = "sssub";
6463
  sssub_optab->libcall_suffix = '3';
6464
  sssub_optab->libcall_gen = gen_signed_fixed_libfunc;
6465
  ussub_optab->libcall_basename = "ussub";
6466
  ussub_optab->libcall_suffix = '3';
6467
  ussub_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6468
  smul_optab->libcall_basename = "mul";
6469
  smul_optab->libcall_suffix = '3';
6470
  smul_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6471
  smulv_optab->libcall_basename = "mul";
6472
  smulv_optab->libcall_suffix = '3';
6473
  smulv_optab->libcall_gen = gen_intv_fp_libfunc;
6474
  ssmul_optab->libcall_basename = "ssmul";
6475
  ssmul_optab->libcall_suffix = '3';
6476
  ssmul_optab->libcall_gen = gen_signed_fixed_libfunc;
6477
  usmul_optab->libcall_basename = "usmul";
6478
  usmul_optab->libcall_suffix = '3';
6479
  usmul_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6480
  sdiv_optab->libcall_basename = "div";
6481
  sdiv_optab->libcall_suffix = '3';
6482
  sdiv_optab->libcall_gen = gen_int_fp_signed_fixed_libfunc;
6483
  sdivv_optab->libcall_basename = "divv";
6484
  sdivv_optab->libcall_suffix = '3';
6485
  sdivv_optab->libcall_gen = gen_int_libfunc;
6486
  ssdiv_optab->libcall_basename = "ssdiv";
6487
  ssdiv_optab->libcall_suffix = '3';
6488
  ssdiv_optab->libcall_gen = gen_signed_fixed_libfunc;
6489
  udiv_optab->libcall_basename = "udiv";
6490
  udiv_optab->libcall_suffix = '3';
6491
  udiv_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6492
  usdiv_optab->libcall_basename = "usdiv";
6493
  usdiv_optab->libcall_suffix = '3';
6494
  usdiv_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6495
  sdivmod_optab->libcall_basename = "divmod";
6496
  sdivmod_optab->libcall_suffix = '4';
6497
  sdivmod_optab->libcall_gen = gen_int_libfunc;
6498
  udivmod_optab->libcall_basename = "udivmod";
6499
  udivmod_optab->libcall_suffix = '4';
6500
  udivmod_optab->libcall_gen = gen_int_libfunc;
6501
  smod_optab->libcall_basename = "mod";
6502
  smod_optab->libcall_suffix = '3';
6503
  smod_optab->libcall_gen = gen_int_libfunc;
6504
  umod_optab->libcall_basename = "umod";
6505
  umod_optab->libcall_suffix = '3';
6506
  umod_optab->libcall_gen = gen_int_libfunc;
6507
  ftrunc_optab->libcall_basename = "ftrunc";
6508
  ftrunc_optab->libcall_suffix = '2';
6509
  ftrunc_optab->libcall_gen = gen_fp_libfunc;
6510
  and_optab->libcall_basename = "and";
6511
  and_optab->libcall_suffix = '3';
6512
  and_optab->libcall_gen = gen_int_libfunc;
6513
  ior_optab->libcall_basename = "ior";
6514
  ior_optab->libcall_suffix = '3';
6515
  ior_optab->libcall_gen = gen_int_libfunc;
6516
  xor_optab->libcall_basename = "xor";
6517
  xor_optab->libcall_suffix = '3';
6518
  xor_optab->libcall_gen = gen_int_libfunc;
6519
  ashl_optab->libcall_basename = "ashl";
6520
  ashl_optab->libcall_suffix = '3';
6521
  ashl_optab->libcall_gen = gen_int_fixed_libfunc;
6522
  ssashl_optab->libcall_basename = "ssashl";
6523
  ssashl_optab->libcall_suffix = '3';
6524
  ssashl_optab->libcall_gen = gen_signed_fixed_libfunc;
6525
  usashl_optab->libcall_basename = "usashl";
6526
  usashl_optab->libcall_suffix = '3';
6527
  usashl_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6528
  ashr_optab->libcall_basename = "ashr";
6529
  ashr_optab->libcall_suffix = '3';
6530
  ashr_optab->libcall_gen = gen_int_signed_fixed_libfunc;
6531
  lshr_optab->libcall_basename = "lshr";
6532
  lshr_optab->libcall_suffix = '3';
6533
  lshr_optab->libcall_gen = gen_int_unsigned_fixed_libfunc;
6534
  smin_optab->libcall_basename = "min";
6535
  smin_optab->libcall_suffix = '3';
6536
  smin_optab->libcall_gen = gen_int_fp_libfunc;
6537
  smax_optab->libcall_basename = "max";
6538
  smax_optab->libcall_suffix = '3';
6539
  smax_optab->libcall_gen = gen_int_fp_libfunc;
6540
  umin_optab->libcall_basename = "umin";
6541
  umin_optab->libcall_suffix = '3';
6542
  umin_optab->libcall_gen = gen_int_libfunc;
6543
  umax_optab->libcall_basename = "umax";
6544
  umax_optab->libcall_suffix = '3';
6545
  umax_optab->libcall_gen = gen_int_libfunc;
6546
  neg_optab->libcall_basename = "neg";
6547
  neg_optab->libcall_suffix = '2';
6548
  neg_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6549
  ssneg_optab->libcall_basename = "ssneg";
6550
  ssneg_optab->libcall_suffix = '2';
6551
  ssneg_optab->libcall_gen = gen_signed_fixed_libfunc;
6552
  usneg_optab->libcall_basename = "usneg";
6553
  usneg_optab->libcall_suffix = '2';
6554
  usneg_optab->libcall_gen = gen_unsigned_fixed_libfunc;
6555
  negv_optab->libcall_basename = "neg";
6556
  negv_optab->libcall_suffix = '2';
6557
  negv_optab->libcall_gen = gen_intv_fp_libfunc;
6558
  one_cmpl_optab->libcall_basename = "one_cmpl";
6559
  one_cmpl_optab->libcall_suffix = '2';
6560
  one_cmpl_optab->libcall_gen = gen_int_libfunc;
6561
  ffs_optab->libcall_basename = "ffs";
6562
  ffs_optab->libcall_suffix = '2';
6563
  ffs_optab->libcall_gen = gen_int_libfunc;
6564
  clz_optab->libcall_basename = "clz";
6565
  clz_optab->libcall_suffix = '2';
6566
  clz_optab->libcall_gen = gen_int_libfunc;
6567
  ctz_optab->libcall_basename = "ctz";
6568
  ctz_optab->libcall_suffix = '2';
6569
  ctz_optab->libcall_gen = gen_int_libfunc;
6570
  popcount_optab->libcall_basename = "popcount";
6571
  popcount_optab->libcall_suffix = '2';
6572
  popcount_optab->libcall_gen = gen_int_libfunc;
6573
  parity_optab->libcall_basename = "parity";
6574
  parity_optab->libcall_suffix = '2';
6575
  parity_optab->libcall_gen = gen_int_libfunc;
6576
 
6577
  /* Comparison libcalls for integers MUST come in pairs,
6578
     signed/unsigned.  */
6579
  cmp_optab->libcall_basename = "cmp";
6580
  cmp_optab->libcall_suffix = '2';
6581
  cmp_optab->libcall_gen = gen_int_fp_fixed_libfunc;
6582
  ucmp_optab->libcall_basename = "ucmp";
6583
  ucmp_optab->libcall_suffix = '2';
6584
  ucmp_optab->libcall_gen = gen_int_libfunc;
6585
 
6586
  /* EQ etc are floating point only.  */
6587
  eq_optab->libcall_basename = "eq";
6588
  eq_optab->libcall_suffix = '2';
6589
  eq_optab->libcall_gen = gen_fp_libfunc;
6590
  ne_optab->libcall_basename = "ne";
6591
  ne_optab->libcall_suffix = '2';
6592
  ne_optab->libcall_gen = gen_fp_libfunc;
6593
  gt_optab->libcall_basename = "gt";
6594
  gt_optab->libcall_suffix = '2';
6595
  gt_optab->libcall_gen = gen_fp_libfunc;
6596
  ge_optab->libcall_basename = "ge";
6597
  ge_optab->libcall_suffix = '2';
6598
  ge_optab->libcall_gen = gen_fp_libfunc;
6599
  lt_optab->libcall_basename = "lt";
6600
  lt_optab->libcall_suffix = '2';
6601
  lt_optab->libcall_gen = gen_fp_libfunc;
6602
  le_optab->libcall_basename = "le";
6603
  le_optab->libcall_suffix = '2';
6604
  le_optab->libcall_gen = gen_fp_libfunc;
6605
  unord_optab->libcall_basename = "unord";
6606
  unord_optab->libcall_suffix = '2';
6607
  unord_optab->libcall_gen = gen_fp_libfunc;
6608
 
6609
  powi_optab->libcall_basename = "powi";
6610
  powi_optab->libcall_suffix = '2';
6611
  powi_optab->libcall_gen = gen_fp_libfunc;
6612
 
6613
  /* Conversions.  */
6614
  sfloat_optab->libcall_basename = "float";
6615
  sfloat_optab->libcall_gen = gen_int_to_fp_conv_libfunc;
6616
  ufloat_optab->libcall_gen = gen_ufloat_conv_libfunc;
6617
  sfix_optab->libcall_basename = "fix";
6618
  sfix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6619
  ufix_optab->libcall_basename = "fixuns";
6620
  ufix_optab->libcall_gen = gen_fp_to_int_conv_libfunc;
6621
  lrint_optab->libcall_basename = "lrint";
6622
  lrint_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6623
  lround_optab->libcall_basename = "lround";
6624
  lround_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6625
  lfloor_optab->libcall_basename = "lfloor";
6626
  lfloor_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6627
  lceil_optab->libcall_basename = "lceil";
6628
  lceil_optab->libcall_gen = gen_int_to_fp_nondecimal_conv_libfunc;
6629
 
6630
  /* trunc_optab is also used for FLOAT_EXTEND.  */
6631
  sext_optab->libcall_basename = "extend";
6632
  sext_optab->libcall_gen = gen_extend_conv_libfunc;
6633
  trunc_optab->libcall_basename = "trunc";
6634
  trunc_optab->libcall_gen = gen_trunc_conv_libfunc;
6635
 
6636
  /* Conversions for fixed-point modes and other modes.  */
6637
  fract_optab->libcall_basename = "fract";
6638
  fract_optab->libcall_gen = gen_fract_conv_libfunc;
6639
  satfract_optab->libcall_basename = "satfract";
6640
  satfract_optab->libcall_gen = gen_satfract_conv_libfunc;
6641
  fractuns_optab->libcall_basename = "fractuns";
6642
  fractuns_optab->libcall_gen = gen_fractuns_conv_libfunc;
6643
  satfractuns_optab->libcall_basename = "satfractuns";
6644
  satfractuns_optab->libcall_gen = gen_satfractuns_conv_libfunc;
6645
 
6646
  /* The ffs function operates on `int'.  Fall back on it if we do not
6647
     have a libgcc2 function for that width.  */
6648
  if (INT_TYPE_SIZE < BITS_PER_WORD)
6649
    set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
6650
                       "ffs");
6651
 
6652
  /* Explicitly initialize the bswap libfuncs since we need them to be
6653
     valid for things other than word_mode.  */
6654
  set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6655
  set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6656
 
6657
  /* Use cabs for double complex abs, since systems generally have cabs.
6658
     Don't define any libcall for float complex, so that cabs will be used.  */
6659
  if (complex_double_type_node)
6660
    set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node), "cabs");
6661
 
6662
  abort_libfunc = init_one_libfunc ("abort");
6663
  memcpy_libfunc = init_one_libfunc ("memcpy");
6664
  memmove_libfunc = init_one_libfunc ("memmove");
6665
  memcmp_libfunc = init_one_libfunc ("memcmp");
6666
  memset_libfunc = init_one_libfunc ("memset");
6667
  setbits_libfunc = init_one_libfunc ("__setbits");
6668
 
6669
#ifndef DONT_USE_BUILTIN_SETJMP
6670
  setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6671
  longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6672
#else
6673
  setjmp_libfunc = init_one_libfunc ("setjmp");
6674
  longjmp_libfunc = init_one_libfunc ("longjmp");
6675
#endif
6676
  unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6677
  unwind_sjlj_unregister_libfunc
6678
    = init_one_libfunc ("_Unwind_SjLj_Unregister");
6679
 
6680
  /* For function entry/exit instrumentation.  */
6681
  profile_function_entry_libfunc
6682
    = init_one_libfunc ("__cyg_profile_func_enter");
6683
  profile_function_exit_libfunc
6684
    = init_one_libfunc ("__cyg_profile_func_exit");
6685
 
6686
  gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6687
 
6688
  /* Allow the target to add more libcalls or rename some, etc.  */
6689
  targetm.init_libfuncs ();
6690
 
6691
  reinit = true;
6692
}
6693
 
6694
/* Print information about the current contents of the optabs on
6695
   STDERR.  */
6696
 
6697
void
6698
debug_optab_libfuncs (void)
6699
{
6700
  int i;
6701
  int j;
6702
  int k;
6703
 
6704
  /* Dump the arithmetic optabs.  */
6705
  for (i = 0; i != (int) OTI_MAX; i++)
6706
    for (j = 0; j < NUM_MACHINE_MODES; ++j)
6707
      {
6708
        optab o;
6709
        rtx l;
6710
 
6711
        o = &optab_table[i];
6712
        l = optab_libfunc (o, (enum machine_mode) j);
6713
        if (l)
6714
          {
6715
            gcc_assert (GET_CODE (l) == SYMBOL_REF);
6716
            fprintf (stderr, "%s\t%s:\t%s\n",
6717
                     GET_RTX_NAME (o->code),
6718
                     GET_MODE_NAME (j),
6719
                     XSTR (l, 0));
6720
          }
6721
      }
6722
 
6723
  /* Dump the conversion optabs.  */
6724
  for (i = 0; i < (int) COI_MAX; ++i)
6725
    for (j = 0; j < NUM_MACHINE_MODES; ++j)
6726
      for (k = 0; k < NUM_MACHINE_MODES; ++k)
6727
        {
6728
          convert_optab o;
6729
          rtx l;
6730
 
6731
          o = &convert_optab_table[i];
6732
          l = convert_optab_libfunc (o, (enum machine_mode) j,
6733
                                     (enum machine_mode) k);
6734
          if (l)
6735
            {
6736
              gcc_assert (GET_CODE (l) == SYMBOL_REF);
6737
              fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6738
                       GET_RTX_NAME (o->code),
6739
                       GET_MODE_NAME (j),
6740
                       GET_MODE_NAME (k),
6741
                       XSTR (l, 0));
6742
            }
6743
        }
6744
}
6745
 
6746
 
6747
/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6748
   CODE.  Return 0 on failure.  */
6749
 
6750
rtx
6751
gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
6752
{
6753
  enum machine_mode mode = GET_MODE (op1);
6754
  enum insn_code icode;
6755
  rtx insn;
6756
  rtx trap_rtx;
6757
 
6758
  if (mode == VOIDmode)
6759
    return 0;
6760
 
6761
  icode = optab_handler (ctrap_optab, mode)->insn_code;
6762
  if (icode == CODE_FOR_nothing)
6763
    return 0;
6764
 
6765
  /* Some targets only accept a zero trap code.  */
6766
  if (insn_data[icode].operand[3].predicate
6767
      && !insn_data[icode].operand[3].predicate (tcode, VOIDmode))
6768
    return 0;
6769
 
6770
  do_pending_stack_adjust ();
6771
  start_sequence ();
6772
  prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
6773
                    &trap_rtx, &mode);
6774
  if (!trap_rtx)
6775
    insn = NULL_RTX;
6776
  else
6777
    insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
6778
                            tcode);
6779
 
6780
  /* If that failed, then give up.  */
6781
  if (insn == 0)
6782
    {
6783
      end_sequence ();
6784
      return 0;
6785
    }
6786
 
6787
  emit_insn (insn);
6788
  insn = get_insns ();
6789
  end_sequence ();
6790
  return insn;
6791
}
6792
 
6793
/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6794
   or unsigned operation code.  */
6795
 
6796
static enum rtx_code
6797
get_rtx_code (enum tree_code tcode, bool unsignedp)
6798
{
6799
  enum rtx_code code;
6800
  switch (tcode)
6801
    {
6802
    case EQ_EXPR:
6803
      code = EQ;
6804
      break;
6805
    case NE_EXPR:
6806
      code = NE;
6807
      break;
6808
    case LT_EXPR:
6809
      code = unsignedp ? LTU : LT;
6810
      break;
6811
    case LE_EXPR:
6812
      code = unsignedp ? LEU : LE;
6813
      break;
6814
    case GT_EXPR:
6815
      code = unsignedp ? GTU : GT;
6816
      break;
6817
    case GE_EXPR:
6818
      code = unsignedp ? GEU : GE;
6819
      break;
6820
 
6821
    case UNORDERED_EXPR:
6822
      code = UNORDERED;
6823
      break;
6824
    case ORDERED_EXPR:
6825
      code = ORDERED;
6826
      break;
6827
    case UNLT_EXPR:
6828
      code = UNLT;
6829
      break;
6830
    case UNLE_EXPR:
6831
      code = UNLE;
6832
      break;
6833
    case UNGT_EXPR:
6834
      code = UNGT;
6835
      break;
6836
    case UNGE_EXPR:
6837
      code = UNGE;
6838
      break;
6839
    case UNEQ_EXPR:
6840
      code = UNEQ;
6841
      break;
6842
    case LTGT_EXPR:
6843
      code = LTGT;
6844
      break;
6845
 
6846
    default:
6847
      gcc_unreachable ();
6848
    }
6849
  return code;
6850
}
6851
 
6852
/* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6853
   unsigned operators. Do not generate compare instruction.  */
6854
 
6855
static rtx
6856
vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6857
{
6858
  enum rtx_code rcode;
6859
  tree t_op0, t_op1;
6860
  rtx rtx_op0, rtx_op1;
6861
 
6862
  /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6863
     ensures that condition is a relational operation.  */
6864
  gcc_assert (COMPARISON_CLASS_P (cond));
6865
 
6866
  rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6867
  t_op0 = TREE_OPERAND (cond, 0);
6868
  t_op1 = TREE_OPERAND (cond, 1);
6869
 
6870
  /* Expand operands.  */
6871
  rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6872
                         EXPAND_STACK_PARM);
6873
  rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6874
                         EXPAND_STACK_PARM);
6875
 
6876
  if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
6877
      && GET_MODE (rtx_op0) != VOIDmode)
6878
    rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
6879
 
6880
  if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
6881
      && GET_MODE (rtx_op1) != VOIDmode)
6882
    rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
6883
 
6884
  return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
6885
}
6886
 
6887
/* Return insn code for TYPE, the type of a VEC_COND_EXPR.  */
6888
 
6889
static inline enum insn_code
6890
get_vcond_icode (tree type, enum machine_mode mode)
6891
{
6892
  enum insn_code icode = CODE_FOR_nothing;
6893
 
6894
  if (TYPE_UNSIGNED (type))
6895
    icode = vcondu_gen_code[mode];
6896
  else
6897
    icode = vcond_gen_code[mode];
6898
  return icode;
6899
}
6900
 
6901
/* Return TRUE iff, appropriate vector insns are available
6902
   for vector cond expr with type TYPE in VMODE mode.  */
6903
 
6904
bool
6905
expand_vec_cond_expr_p (tree type, enum machine_mode vmode)
6906
{
6907
  if (get_vcond_icode (type, vmode) == CODE_FOR_nothing)
6908
    return false;
6909
  return true;
6910
}
6911
 
6912
/* Generate insns for a VEC_COND_EXPR, given its TYPE and its
6913
   three operands.  */
6914
 
6915
rtx
6916
expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
6917
                      rtx target)
6918
{
6919
  enum insn_code icode;
6920
  rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
6921
  enum machine_mode mode = TYPE_MODE (vec_cond_type);
6922
  bool unsignedp = TYPE_UNSIGNED (vec_cond_type);
6923
 
6924
  icode = get_vcond_icode (vec_cond_type, mode);
6925
  if (icode == CODE_FOR_nothing)
6926
    return 0;
6927
 
6928
  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6929
    target = gen_reg_rtx (mode);
6930
 
6931
  /* Get comparison rtx.  First expand both cond expr operands.  */
6932
  comparison = vector_compare_rtx (op0,
6933
                                   unsignedp, icode);
6934
  cc_op0 = XEXP (comparison, 0);
6935
  cc_op1 = XEXP (comparison, 1);
6936
  /* Expand both operands and force them in reg, if required.  */
6937
  rtx_op1 = expand_normal (op1);
6938
  if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
6939
      && mode != VOIDmode)
6940
    rtx_op1 = force_reg (mode, rtx_op1);
6941
 
6942
  rtx_op2 = expand_normal (op2);
6943
  if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
6944
      && mode != VOIDmode)
6945
    rtx_op2 = force_reg (mode, rtx_op2);
6946
 
6947
  /* Emit instruction! */
6948
  emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
6949
                              comparison, cc_op0,  cc_op1));
6950
 
6951
  return target;
6952
}
6953
 
6954
 
6955
/* This is an internal subroutine of the other compare_and_swap expanders.
6956
   MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6957
   operation.  TARGET is an optional place to store the value result of
6958
   the operation.  ICODE is the particular instruction to expand.  Return
6959
   the result of the operation.  */
6960
 
6961
static rtx
6962
expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6963
                               rtx target, enum insn_code icode)
6964
{
6965
  enum machine_mode mode = GET_MODE (mem);
6966
  rtx insn;
6967
 
6968
  if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6969
    target = gen_reg_rtx (mode);
6970
 
6971
  if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
6972
    old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
6973
  if (!insn_data[icode].operand[2].predicate (old_val, mode))
6974
    old_val = force_reg (mode, old_val);
6975
 
6976
  if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
6977
    new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
6978
  if (!insn_data[icode].operand[3].predicate (new_val, mode))
6979
    new_val = force_reg (mode, new_val);
6980
 
6981
  insn = GEN_FCN (icode) (target, mem, old_val, new_val);
6982
  if (insn == NULL_RTX)
6983
    return NULL_RTX;
6984
  emit_insn (insn);
6985
 
6986
  return target;
6987
}
6988
 
6989
/* Expand a compare-and-swap operation and return its value.  */
6990
 
6991
rtx
6992
expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6993
{
6994
  enum machine_mode mode = GET_MODE (mem);
6995
  enum insn_code icode = sync_compare_and_swap[mode];
6996
 
6997
  if (icode == CODE_FOR_nothing)
6998
    return NULL_RTX;
6999
 
7000
  return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
7001
}
7002
 
7003
/* Helper function to find the MODE_CC set in a sync_compare_and_swap
7004
   pattern.  */
7005
 
7006
static void
7007
find_cc_set (rtx x, const_rtx pat, void *data)
7008
{
7009
  if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
7010
      && GET_CODE (pat) == SET)
7011
    {
7012
      rtx *p_cc_reg = (rtx *) data;
7013
      gcc_assert (!*p_cc_reg);
7014
      *p_cc_reg = x;
7015
    }
7016
}
7017
 
7018
/* Expand a compare-and-swap operation and store true into the result if
7019
   the operation was successful and false otherwise.  Return the result.
7020
   Unlike other routines, TARGET is not optional.  */
7021
 
7022
rtx
7023
expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
7024
{
7025
  enum machine_mode mode = GET_MODE (mem);
7026
  enum insn_code icode;
7027
  rtx subtarget, seq, cc_reg;
7028
 
7029
  /* If the target supports a compare-and-swap pattern that simultaneously
7030
     sets some flag for success, then use it.  Otherwise use the regular
7031
     compare-and-swap and follow that immediately with a compare insn.  */
7032
  icode = sync_compare_and_swap[mode];
7033
  if (icode == CODE_FOR_nothing)
7034
    return NULL_RTX;
7035
 
7036 378 julius
  do_pending_stack_adjust ();
7037 280 jeremybenn
  do
7038
    {
7039
      start_sequence ();
7040
      subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
7041
                                                 NULL_RTX, icode);
7042
      cc_reg = NULL_RTX;
7043
      if (subtarget == NULL_RTX)
7044
        {
7045
          end_sequence ();
7046
          return NULL_RTX;
7047
        }
7048
 
7049
      if (have_insn_for (COMPARE, CCmode))
7050
        note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
7051
      seq = get_insns ();
7052
      end_sequence ();
7053
 
7054
      /* We might be comparing against an old value.  Try again. :-(  */
7055
      if (!cc_reg && MEM_P (old_val))
7056
        {
7057
          seq = NULL_RTX;
7058
          old_val = force_reg (mode, old_val);
7059
        }
7060
    }
7061
  while (!seq);
7062
 
7063
  emit_insn (seq);
7064
  if (cc_reg)
7065
    return emit_store_flag_force (target, EQ, cc_reg, const0_rtx, VOIDmode, 0, 1);
7066
  else
7067
    return emit_store_flag_force (target, EQ, subtarget, old_val, VOIDmode, 1, 1);
7068
}
7069
 
7070
/* This is a helper function for the other atomic operations.  This function
7071
   emits a loop that contains SEQ that iterates until a compare-and-swap
7072
   operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
7073
   a set of instructions that takes a value from OLD_REG as an input and
7074
   produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
7075
   set to the current contents of MEM.  After SEQ, a compare-and-swap will
7076
   attempt to update MEM with NEW_REG.  The function returns true when the
7077
   loop was generated successfully.  */
7078
 
7079
static bool
7080
expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
7081
{
7082
  enum machine_mode mode = GET_MODE (mem);
7083
  enum insn_code icode;
7084
  rtx label, cmp_reg, subtarget, cc_reg;
7085
 
7086
  /* The loop we want to generate looks like
7087
 
7088
        cmp_reg = mem;
7089
      label:
7090
        old_reg = cmp_reg;
7091
        seq;
7092
        cmp_reg = compare-and-swap(mem, old_reg, new_reg)
7093
        if (cmp_reg != old_reg)
7094
          goto label;
7095
 
7096
     Note that we only do the plain load from memory once.  Subsequent
7097
     iterations use the value loaded by the compare-and-swap pattern.  */
7098
 
7099
  label = gen_label_rtx ();
7100
  cmp_reg = gen_reg_rtx (mode);
7101
 
7102
  emit_move_insn (cmp_reg, mem);
7103
  emit_label (label);
7104
  emit_move_insn (old_reg, cmp_reg);
7105
  if (seq)
7106
    emit_insn (seq);
7107
 
7108
  /* If the target supports a compare-and-swap pattern that simultaneously
7109
     sets some flag for success, then use it.  Otherwise use the regular
7110
     compare-and-swap and follow that immediately with a compare insn.  */
7111
  icode = sync_compare_and_swap[mode];
7112
  if (icode == CODE_FOR_nothing)
7113
    return false;
7114
 
7115
  subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
7116
                                             cmp_reg, icode);
7117
  if (subtarget == NULL_RTX)
7118
    return false;
7119
 
7120
  cc_reg = NULL_RTX;
7121
  if (have_insn_for (COMPARE, CCmode))
7122
    note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
7123
  if (cc_reg)
7124
    {
7125
      cmp_reg = cc_reg;
7126
      old_reg = const0_rtx;
7127
    }
7128
  else
7129
    {
7130
      if (subtarget != cmp_reg)
7131
        emit_move_insn (cmp_reg, subtarget);
7132
    }
7133
 
7134
  /* ??? Mark this jump predicted not taken?  */
7135
  emit_cmp_and_jump_insns (cmp_reg, old_reg, NE, const0_rtx, GET_MODE (cmp_reg), 1,
7136
                           label);
7137
  return true;
7138
}
7139
 
7140
/* This function generates the atomic operation MEM CODE= VAL.  In this
7141
   case, we do not care about any resulting value.  Returns NULL if we
7142
   cannot generate the operation.  */
7143
 
7144
rtx
7145
expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
7146
{
7147
  enum machine_mode mode = GET_MODE (mem);
7148
  enum insn_code icode;
7149
  rtx insn;
7150
 
7151
  /* Look to see if the target supports the operation directly.  */
7152
  switch (code)
7153
    {
7154
    case PLUS:
7155
      icode = sync_add_optab[mode];
7156
      break;
7157
    case IOR:
7158
      icode = sync_ior_optab[mode];
7159
      break;
7160
    case XOR:
7161
      icode = sync_xor_optab[mode];
7162
      break;
7163
    case AND:
7164
      icode = sync_and_optab[mode];
7165
      break;
7166
    case NOT:
7167
      icode = sync_nand_optab[mode];
7168
      break;
7169
 
7170
    case MINUS:
7171
      icode = sync_sub_optab[mode];
7172
      if (icode == CODE_FOR_nothing || CONST_INT_P (val))
7173
        {
7174
          icode = sync_add_optab[mode];
7175
          if (icode != CODE_FOR_nothing)
7176
            {
7177
              val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7178
              code = PLUS;
7179
            }
7180
        }
7181
      break;
7182
 
7183
    default:
7184
      gcc_unreachable ();
7185
    }
7186
 
7187
  /* Generate the direct operation, if present.  */
7188
  if (icode != CODE_FOR_nothing)
7189
    {
7190
      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7191
        val = convert_modes (mode, GET_MODE (val), val, 1);
7192
      if (!insn_data[icode].operand[1].predicate (val, mode))
7193
        val = force_reg (mode, val);
7194
 
7195
      insn = GEN_FCN (icode) (mem, val);
7196
      if (insn)
7197
        {
7198
          emit_insn (insn);
7199
          return const0_rtx;
7200
        }
7201
    }
7202
 
7203
  /* Failing that, generate a compare-and-swap loop in which we perform the
7204
     operation with normal arithmetic instructions.  */
7205
  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7206
    {
7207
      rtx t0 = gen_reg_rtx (mode), t1;
7208
 
7209
      start_sequence ();
7210
 
7211
      t1 = t0;
7212
      if (code == NOT)
7213
        {
7214
          t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7215
                                    true, OPTAB_LIB_WIDEN);
7216
          t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7217
        }
7218
      else
7219
        t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7220
                                  true, OPTAB_LIB_WIDEN);
7221
      insn = get_insns ();
7222
      end_sequence ();
7223
 
7224
      if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7225
        return const0_rtx;
7226
    }
7227
 
7228
  return NULL_RTX;
7229
}
7230
 
7231
/* This function generates the atomic operation MEM CODE= VAL.  In this
7232
   case, we do care about the resulting value: if AFTER is true then
7233
   return the value MEM holds after the operation, if AFTER is false
7234
   then return the value MEM holds before the operation.  TARGET is an
7235
   optional place for the result value to be stored.  */
7236
 
7237
rtx
7238
expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
7239
                             bool after, rtx target)
7240
{
7241
  enum machine_mode mode = GET_MODE (mem);
7242
  enum insn_code old_code, new_code, icode;
7243
  bool compensate;
7244
  rtx insn;
7245
 
7246
  /* Look to see if the target supports the operation directly.  */
7247
  switch (code)
7248
    {
7249
    case PLUS:
7250
      old_code = sync_old_add_optab[mode];
7251
      new_code = sync_new_add_optab[mode];
7252
      break;
7253
    case IOR:
7254
      old_code = sync_old_ior_optab[mode];
7255
      new_code = sync_new_ior_optab[mode];
7256
      break;
7257
    case XOR:
7258
      old_code = sync_old_xor_optab[mode];
7259
      new_code = sync_new_xor_optab[mode];
7260
      break;
7261
    case AND:
7262
      old_code = sync_old_and_optab[mode];
7263
      new_code = sync_new_and_optab[mode];
7264
      break;
7265
    case NOT:
7266
      old_code = sync_old_nand_optab[mode];
7267
      new_code = sync_new_nand_optab[mode];
7268
      break;
7269
 
7270
    case MINUS:
7271
      old_code = sync_old_sub_optab[mode];
7272
      new_code = sync_new_sub_optab[mode];
7273
      if ((old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
7274
          || CONST_INT_P (val))
7275
        {
7276
          old_code = sync_old_add_optab[mode];
7277
          new_code = sync_new_add_optab[mode];
7278
          if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
7279
            {
7280
              val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
7281
              code = PLUS;
7282
            }
7283
        }
7284
      break;
7285
 
7286
    default:
7287
      gcc_unreachable ();
7288
    }
7289
 
7290
  /* If the target does supports the proper new/old operation, great.  But
7291
     if we only support the opposite old/new operation, check to see if we
7292
     can compensate.  In the case in which the old value is supported, then
7293
     we can always perform the operation again with normal arithmetic.  In
7294
     the case in which the new value is supported, then we can only handle
7295
     this in the case the operation is reversible.  */
7296
  compensate = false;
7297
  if (after)
7298
    {
7299
      icode = new_code;
7300
      if (icode == CODE_FOR_nothing)
7301
        {
7302
          icode = old_code;
7303
          if (icode != CODE_FOR_nothing)
7304
            compensate = true;
7305
        }
7306
    }
7307
  else
7308
    {
7309
      icode = old_code;
7310
      if (icode == CODE_FOR_nothing
7311
          && (code == PLUS || code == MINUS || code == XOR))
7312
        {
7313
          icode = new_code;
7314
          if (icode != CODE_FOR_nothing)
7315
            compensate = true;
7316
        }
7317
    }
7318
 
7319
  /* If we found something supported, great.  */
7320
  if (icode != CODE_FOR_nothing)
7321
    {
7322
      if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7323
        target = gen_reg_rtx (mode);
7324
 
7325
      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7326
        val = convert_modes (mode, GET_MODE (val), val, 1);
7327
      if (!insn_data[icode].operand[2].predicate (val, mode))
7328
        val = force_reg (mode, val);
7329
 
7330
      insn = GEN_FCN (icode) (target, mem, val);
7331
      if (insn)
7332
        {
7333
          emit_insn (insn);
7334
 
7335
          /* If we need to compensate for using an operation with the
7336
             wrong return value, do so now.  */
7337
          if (compensate)
7338
            {
7339
              if (!after)
7340
                {
7341
                  if (code == PLUS)
7342
                    code = MINUS;
7343
                  else if (code == MINUS)
7344
                    code = PLUS;
7345
                }
7346
 
7347
              if (code == NOT)
7348
                {
7349
                  target = expand_simple_binop (mode, AND, target, val,
7350
                                                NULL_RTX, true,
7351
                                                OPTAB_LIB_WIDEN);
7352
                  target = expand_simple_unop (mode, code, target,
7353
                                               NULL_RTX, true);
7354
                }
7355
              else
7356
                target = expand_simple_binop (mode, code, target, val,
7357
                                              NULL_RTX, true,
7358
                                              OPTAB_LIB_WIDEN);
7359
            }
7360
 
7361
          return target;
7362
        }
7363
    }
7364
 
7365
  /* Failing that, generate a compare-and-swap loop in which we perform the
7366
     operation with normal arithmetic instructions.  */
7367
  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7368
    {
7369
      rtx t0 = gen_reg_rtx (mode), t1;
7370
 
7371
      if (!target || !register_operand (target, mode))
7372
        target = gen_reg_rtx (mode);
7373
 
7374
      start_sequence ();
7375
 
7376
      if (!after)
7377
        emit_move_insn (target, t0);
7378
      t1 = t0;
7379
      if (code == NOT)
7380
        {
7381
          t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7382
                                    true, OPTAB_LIB_WIDEN);
7383
          t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7384
        }
7385
      else
7386
        t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
7387
                                  true, OPTAB_LIB_WIDEN);
7388
      if (after)
7389
        emit_move_insn (target, t1);
7390
 
7391
      insn = get_insns ();
7392
      end_sequence ();
7393
 
7394
      if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7395
        return target;
7396
    }
7397
 
7398
  return NULL_RTX;
7399
}
7400
 
7401
/* This function expands a test-and-set operation.  Ideally we atomically
7402
   store VAL in MEM and return the previous value in MEM.  Some targets
7403
   may not support this operation and only support VAL with the constant 1;
7404
   in this case while the return value will be 0/1, but the exact value
7405
   stored in MEM is target defined.  TARGET is an option place to stick
7406
   the return value.  */
7407
 
7408
rtx
7409
expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
7410
{
7411
  enum machine_mode mode = GET_MODE (mem);
7412
  enum insn_code icode;
7413
  rtx insn;
7414
 
7415
  /* If the target supports the test-and-set directly, great.  */
7416
  icode = sync_lock_test_and_set[mode];
7417
  if (icode != CODE_FOR_nothing)
7418
    {
7419
      if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7420
        target = gen_reg_rtx (mode);
7421
 
7422
      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7423
        val = convert_modes (mode, GET_MODE (val), val, 1);
7424
      if (!insn_data[icode].operand[2].predicate (val, mode))
7425
        val = force_reg (mode, val);
7426
 
7427
      insn = GEN_FCN (icode) (target, mem, val);
7428
      if (insn)
7429
        {
7430
          emit_insn (insn);
7431
          return target;
7432
        }
7433
    }
7434
 
7435
  /* Otherwise, use a compare-and-swap loop for the exchange.  */
7436
  if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
7437
    {
7438
      if (!target || !register_operand (target, mode))
7439
        target = gen_reg_rtx (mode);
7440
      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
7441
        val = convert_modes (mode, GET_MODE (val), val, 1);
7442
      if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
7443
        return target;
7444
    }
7445
 
7446
  return NULL_RTX;
7447
}
7448
 
7449
#include "gt-optabs.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.