Home | History | Annotate | Line # | Download | only in gcc
expmed.h revision 1.7
      1  1.1  mrg /* Target-dependent costs for expmed.c.
      2  1.7  mrg    Copyright (C) 1987-2018 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg the terms of the GNU General Public License as published by the Free
      8  1.6  mrg Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg #ifndef EXPMED_H
     21  1.1  mrg #define EXPMED_H 1
     22  1.1  mrg 
     23  1.3  mrg #include "insn-codes.h"
     24  1.3  mrg 
     25  1.1  mrg enum alg_code {
     26  1.1  mrg   alg_unknown,
     27  1.1  mrg   alg_zero,
     28  1.1  mrg   alg_m, alg_shift,
     29  1.1  mrg   alg_add_t_m2,
     30  1.1  mrg   alg_sub_t_m2,
     31  1.1  mrg   alg_add_factor,
     32  1.1  mrg   alg_sub_factor,
     33  1.1  mrg   alg_add_t2_m,
     34  1.1  mrg   alg_sub_t2_m,
     35  1.1  mrg   alg_impossible
     36  1.1  mrg };
     37  1.1  mrg 
     38  1.6  mrg /* Indicates the type of fixup needed after a constant multiplication.
     39  1.6  mrg    BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that
     40  1.6  mrg    the result should be negated, and ADD_VARIANT means that the
     41  1.6  mrg    multiplicand should be added to the result.  */
     42  1.6  mrg enum mult_variant {basic_variant, negate_variant, add_variant};
     43  1.6  mrg 
     44  1.6  mrg bool choose_mult_variant (machine_mode, HOST_WIDE_INT,
     45  1.6  mrg 			  struct algorithm *, enum mult_variant *, int);
     46  1.6  mrg 
     47  1.1  mrg /* This structure holds the "cost" of a multiply sequence.  The
     48  1.1  mrg    "cost" field holds the total rtx_cost of every operator in the
     49  1.1  mrg    synthetic multiplication sequence, hence cost(a op b) is defined
     50  1.1  mrg    as rtx_cost(op) + cost(a) + cost(b), where cost(leaf) is zero.
     51  1.1  mrg    The "latency" field holds the minimum possible latency of the
     52  1.1  mrg    synthetic multiply, on a hypothetical infinitely parallel CPU.
     53  1.1  mrg    This is the critical path, or the maximum height, of the expression
     54  1.1  mrg    tree which is the sum of rtx_costs on the most expensive path from
     55  1.1  mrg    any leaf to the root.  Hence latency(a op b) is defined as zero for
     56  1.1  mrg    leaves and rtx_cost(op) + max(latency(a), latency(b)) otherwise.  */
     57  1.1  mrg 
     58  1.1  mrg struct mult_cost {
     59  1.1  mrg   short cost;     /* Total rtx_cost of the multiplication sequence.  */
     60  1.1  mrg   short latency;  /* The latency of the multiplication sequence.  */
     61  1.1  mrg };
     62  1.1  mrg 
     63  1.1  mrg /* This macro is used to compare a pointer to a mult_cost against an
     64  1.1  mrg    single integer "rtx_cost" value.  This is equivalent to the macro
     65  1.1  mrg    CHEAPER_MULT_COST(X,Z) where Z = {Y,Y}.  */
     66  1.1  mrg #define MULT_COST_LESS(X,Y) ((X)->cost < (Y)	\
     67  1.1  mrg 			     || ((X)->cost == (Y) && (X)->latency < (Y)))
     68  1.1  mrg 
     69  1.1  mrg /* This macro is used to compare two pointers to mult_costs against
     70  1.1  mrg    each other.  The macro returns true if X is cheaper than Y.
     71  1.1  mrg    Currently, the cheaper of two mult_costs is the one with the
     72  1.1  mrg    lower "cost".  If "cost"s are tied, the lower latency is cheaper.  */
     73  1.1  mrg #define CHEAPER_MULT_COST(X,Y)  ((X)->cost < (Y)->cost		\
     74  1.1  mrg 				 || ((X)->cost == (Y)->cost	\
     75  1.1  mrg 				     && (X)->latency < (Y)->latency))
     76  1.1  mrg 
     77  1.1  mrg /* This structure records a sequence of operations.
     78  1.1  mrg    `ops' is the number of operations recorded.
     79  1.1  mrg    `cost' is their total cost.
     80  1.1  mrg    The operations are stored in `op' and the corresponding
     81  1.1  mrg    logarithms of the integer coefficients in `log'.
     82  1.1  mrg 
     83  1.1  mrg    These are the operations:
     84  1.1  mrg    alg_zero		total := 0;
     85  1.1  mrg    alg_m		total := multiplicand;
     86  1.1  mrg    alg_shift		total := total * coeff
     87  1.1  mrg    alg_add_t_m2		total := total + multiplicand * coeff;
     88  1.1  mrg    alg_sub_t_m2		total := total - multiplicand * coeff;
     89  1.1  mrg    alg_add_factor	total := total * coeff + total;
     90  1.1  mrg    alg_sub_factor	total := total * coeff - total;
     91  1.1  mrg    alg_add_t2_m		total := total * coeff + multiplicand;
     92  1.1  mrg    alg_sub_t2_m		total := total * coeff - multiplicand;
     93  1.1  mrg 
     94  1.1  mrg    The first operand must be either alg_zero or alg_m.  */
     95  1.1  mrg 
     96  1.1  mrg struct algorithm
     97  1.1  mrg {
     98  1.1  mrg   struct mult_cost cost;
     99  1.1  mrg   short ops;
    100  1.1  mrg   /* The size of the OP and LOG fields are not directly related to the
    101  1.1  mrg      word size, but the worst-case algorithms will be if we have few
    102  1.1  mrg      consecutive ones or zeros, i.e., a multiplicand like 10101010101...
    103  1.1  mrg      In that case we will generate shift-by-2, add, shift-by-2, add,...,
    104  1.1  mrg      in total wordsize operations.  */
    105  1.1  mrg   enum alg_code op[MAX_BITS_PER_WORD];
    106  1.1  mrg   char log[MAX_BITS_PER_WORD];
    107  1.1  mrg };
    108  1.1  mrg 
    109  1.1  mrg /* The entry for our multiplication cache/hash table.  */
    110  1.1  mrg struct alg_hash_entry {
    111  1.1  mrg   /* The number we are multiplying by.  */
    112  1.1  mrg   unsigned HOST_WIDE_INT t;
    113  1.1  mrg 
    114  1.1  mrg   /* The mode in which we are multiplying something by T.  */
    115  1.3  mrg   machine_mode mode;
    116  1.1  mrg 
    117  1.1  mrg   /* The best multiplication algorithm for t.  */
    118  1.1  mrg   enum alg_code alg;
    119  1.1  mrg 
    120  1.1  mrg   /* The cost of multiplication if ALG_CODE is not alg_impossible.
    121  1.1  mrg      Otherwise, the cost within which multiplication by T is
    122  1.1  mrg      impossible.  */
    123  1.1  mrg   struct mult_cost cost;
    124  1.1  mrg 
    125  1.1  mrg   /* Optimized for speed? */
    126  1.1  mrg   bool speed;
    127  1.1  mrg };
    128  1.1  mrg 
    129  1.1  mrg /* The number of cache/hash entries.  */
    130  1.1  mrg #if HOST_BITS_PER_WIDE_INT == 64
    131  1.1  mrg #define NUM_ALG_HASH_ENTRIES 1031
    132  1.1  mrg #else
    133  1.1  mrg #define NUM_ALG_HASH_ENTRIES 307
    134  1.1  mrg #endif
    135  1.1  mrg 
    136  1.1  mrg #define NUM_MODE_INT \
    137  1.1  mrg   (MAX_MODE_INT - MIN_MODE_INT + 1)
    138  1.1  mrg #define NUM_MODE_PARTIAL_INT \
    139  1.7  mrg   (MIN_MODE_PARTIAL_INT == E_VOIDmode ? 0 \
    140  1.1  mrg    : MAX_MODE_PARTIAL_INT - MIN_MODE_PARTIAL_INT + 1)
    141  1.1  mrg #define NUM_MODE_VECTOR_INT \
    142  1.7  mrg   (MIN_MODE_VECTOR_INT == E_VOIDmode ? 0 \
    143  1.1  mrg    : MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1)
    144  1.1  mrg 
    145  1.1  mrg #define NUM_MODE_IP_INT (NUM_MODE_INT + NUM_MODE_PARTIAL_INT)
    146  1.1  mrg #define NUM_MODE_IPV_INT (NUM_MODE_IP_INT + NUM_MODE_VECTOR_INT)
    147  1.1  mrg 
    148  1.1  mrg struct expmed_op_cheap {
    149  1.1  mrg   bool cheap[2][NUM_MODE_IPV_INT];
    150  1.1  mrg };
    151  1.1  mrg 
    152  1.1  mrg struct expmed_op_costs {
    153  1.1  mrg   int cost[2][NUM_MODE_IPV_INT];
    154  1.1  mrg };
    155  1.1  mrg 
    156  1.1  mrg /* Target-dependent globals.  */
    157  1.1  mrg struct target_expmed {
    158  1.1  mrg   /* Each entry of ALG_HASH caches alg_code for some integer.  This is
    159  1.1  mrg      actually a hash table.  If we have a collision, that the older
    160  1.1  mrg      entry is kicked out.  */
    161  1.1  mrg   struct alg_hash_entry x_alg_hash[NUM_ALG_HASH_ENTRIES];
    162  1.1  mrg 
    163  1.1  mrg   /* True if x_alg_hash might already have been used.  */
    164  1.1  mrg   bool x_alg_hash_used_p;
    165  1.1  mrg 
    166  1.1  mrg   /* Nonzero means divides or modulus operations are relatively cheap for
    167  1.1  mrg      powers of two, so don't use branches; emit the operation instead.
    168  1.1  mrg      Usually, this will mean that the MD file will emit non-branch
    169  1.1  mrg      sequences.  */
    170  1.1  mrg   struct expmed_op_cheap x_sdiv_pow2_cheap;
    171  1.1  mrg   struct expmed_op_cheap x_smod_pow2_cheap;
    172  1.1  mrg 
    173  1.1  mrg   /* Cost of various pieces of RTL.  Note that some of these are indexed by
    174  1.1  mrg      shift count and some by mode.  */
    175  1.1  mrg   int x_zero_cost[2];
    176  1.1  mrg   struct expmed_op_costs x_add_cost;
    177  1.1  mrg   struct expmed_op_costs x_neg_cost;
    178  1.1  mrg   struct expmed_op_costs x_shift_cost[MAX_BITS_PER_WORD];
    179  1.1  mrg   struct expmed_op_costs x_shiftadd_cost[MAX_BITS_PER_WORD];
    180  1.1  mrg   struct expmed_op_costs x_shiftsub0_cost[MAX_BITS_PER_WORD];
    181  1.1  mrg   struct expmed_op_costs x_shiftsub1_cost[MAX_BITS_PER_WORD];
    182  1.1  mrg   struct expmed_op_costs x_mul_cost;
    183  1.1  mrg   struct expmed_op_costs x_sdiv_cost;
    184  1.1  mrg   struct expmed_op_costs x_udiv_cost;
    185  1.1  mrg   int x_mul_widen_cost[2][NUM_MODE_INT];
    186  1.1  mrg   int x_mul_highpart_cost[2][NUM_MODE_INT];
    187  1.1  mrg 
    188  1.1  mrg   /* Conversion costs are only defined between two scalar integer modes
    189  1.1  mrg      of different sizes.  The first machine mode is the destination mode,
    190  1.1  mrg      and the second is the source mode.  */
    191  1.1  mrg   int x_convert_cost[2][NUM_MODE_IP_INT][NUM_MODE_IP_INT];
    192  1.1  mrg };
    193  1.1  mrg 
    194  1.1  mrg extern struct target_expmed default_target_expmed;
    195  1.1  mrg #if SWITCHABLE_TARGET
    196  1.1  mrg extern struct target_expmed *this_target_expmed;
    197  1.1  mrg #else
    198  1.1  mrg #define this_target_expmed (&default_target_expmed)
    199  1.1  mrg #endif
    200  1.1  mrg 
    201  1.1  mrg /* Return a pointer to the alg_hash_entry at IDX.  */
    202  1.1  mrg 
    203  1.1  mrg static inline struct alg_hash_entry *
    204  1.1  mrg alg_hash_entry_ptr (int idx)
    205  1.1  mrg {
    206  1.1  mrg   return &this_target_expmed->x_alg_hash[idx];
    207  1.1  mrg }
    208  1.1  mrg 
    209  1.1  mrg /* Return true if the x_alg_hash field might have been used.  */
    210  1.1  mrg 
    211  1.1  mrg static inline bool
    212  1.1  mrg alg_hash_used_p (void)
    213  1.1  mrg {
    214  1.1  mrg   return this_target_expmed->x_alg_hash_used_p;
    215  1.1  mrg }
    216  1.1  mrg 
    217  1.1  mrg /* Set whether the x_alg_hash field might have been used.  */
    218  1.1  mrg 
    219  1.1  mrg static inline void
    220  1.1  mrg set_alg_hash_used_p (bool usedp)
    221  1.1  mrg {
    222  1.1  mrg   this_target_expmed->x_alg_hash_used_p = usedp;
    223  1.1  mrg }
    224  1.1  mrg 
    225  1.1  mrg /* Compute an index into the cost arrays by mode class.  */
    226  1.1  mrg 
    227  1.1  mrg static inline int
    228  1.3  mrg expmed_mode_index (machine_mode mode)
    229  1.1  mrg {
    230  1.1  mrg   switch (GET_MODE_CLASS (mode))
    231  1.1  mrg     {
    232  1.1  mrg     case MODE_INT:
    233  1.1  mrg       return mode - MIN_MODE_INT;
    234  1.1  mrg     case MODE_PARTIAL_INT:
    235  1.3  mrg       /* If there are no partial integer modes, help the compiler
    236  1.3  mrg 	 to figure out this will never happen.  See PR59934.  */
    237  1.3  mrg       if (MIN_MODE_PARTIAL_INT != VOIDmode)
    238  1.3  mrg 	return mode - MIN_MODE_PARTIAL_INT + NUM_MODE_INT;
    239  1.3  mrg       break;
    240  1.1  mrg     case MODE_VECTOR_INT:
    241  1.3  mrg       /* If there are no vector integer modes, help the compiler
    242  1.3  mrg 	 to figure out this will never happen.  See PR59934.  */
    243  1.3  mrg       if (MIN_MODE_VECTOR_INT != VOIDmode)
    244  1.3  mrg 	return mode - MIN_MODE_VECTOR_INT + NUM_MODE_IP_INT;
    245  1.3  mrg       break;
    246  1.1  mrg     default:
    247  1.3  mrg       break;
    248  1.1  mrg     }
    249  1.3  mrg   gcc_unreachable ();
    250  1.1  mrg }
    251  1.1  mrg 
    252  1.1  mrg /* Return a pointer to a boolean contained in EOC indicating whether
    253  1.1  mrg    a particular operation performed in MODE is cheap when optimizing
    254  1.1  mrg    for SPEED.  */
    255  1.1  mrg 
    256  1.1  mrg static inline bool *
    257  1.1  mrg expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed,
    258  1.3  mrg 		     machine_mode mode)
    259  1.1  mrg {
    260  1.1  mrg   int idx = expmed_mode_index (mode);
    261  1.1  mrg   return &eoc->cheap[speed][idx];
    262  1.1  mrg }
    263  1.1  mrg 
    264  1.1  mrg /* Return a pointer to a cost contained in COSTS when a particular
    265  1.1  mrg    operation is performed in MODE when optimizing for SPEED.  */
    266  1.1  mrg 
    267  1.1  mrg static inline int *
    268  1.1  mrg expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed,
    269  1.3  mrg 		    machine_mode mode)
    270  1.1  mrg {
    271  1.1  mrg   int idx = expmed_mode_index (mode);
    272  1.1  mrg   return &costs->cost[speed][idx];
    273  1.1  mrg }
    274  1.1  mrg 
    275  1.1  mrg /* Subroutine of {set_,}sdiv_pow2_cheap.  Not to be used otherwise.  */
    276  1.1  mrg 
    277  1.1  mrg static inline bool *
    278  1.3  mrg sdiv_pow2_cheap_ptr (bool speed, machine_mode mode)
    279  1.1  mrg {
    280  1.1  mrg   return expmed_op_cheap_ptr (&this_target_expmed->x_sdiv_pow2_cheap,
    281  1.1  mrg 			      speed, mode);
    282  1.1  mrg }
    283  1.1  mrg 
    284  1.1  mrg /* Set whether a signed division by a power of 2 is cheap in MODE
    285  1.1  mrg    when optimizing for SPEED.  */
    286  1.1  mrg 
    287  1.1  mrg static inline void
    288  1.3  mrg set_sdiv_pow2_cheap (bool speed, machine_mode mode, bool cheap_p)
    289  1.1  mrg {
    290  1.1  mrg   *sdiv_pow2_cheap_ptr (speed, mode) = cheap_p;
    291  1.1  mrg }
    292  1.1  mrg 
    293  1.1  mrg /* Return whether a signed division by a power of 2 is cheap in MODE
    294  1.1  mrg    when optimizing for SPEED.  */
    295  1.1  mrg 
    296  1.1  mrg static inline bool
    297  1.3  mrg sdiv_pow2_cheap (bool speed, machine_mode mode)
    298  1.1  mrg {
    299  1.1  mrg   return *sdiv_pow2_cheap_ptr (speed, mode);
    300  1.1  mrg }
    301  1.1  mrg 
    302  1.1  mrg /* Subroutine of {set_,}smod_pow2_cheap.  Not to be used otherwise.  */
    303  1.1  mrg 
    304  1.1  mrg static inline bool *
    305  1.3  mrg smod_pow2_cheap_ptr (bool speed, machine_mode mode)
    306  1.1  mrg {
    307  1.1  mrg   return expmed_op_cheap_ptr (&this_target_expmed->x_smod_pow2_cheap,
    308  1.1  mrg 			      speed, mode);
    309  1.1  mrg }
    310  1.1  mrg 
    311  1.1  mrg /* Set whether a signed modulo by a power of 2 is CHEAP in MODE when
    312  1.1  mrg    optimizing for SPEED.  */
    313  1.1  mrg 
    314  1.1  mrg static inline void
    315  1.3  mrg set_smod_pow2_cheap (bool speed, machine_mode mode, bool cheap)
    316  1.1  mrg {
    317  1.1  mrg   *smod_pow2_cheap_ptr (speed, mode) = cheap;
    318  1.1  mrg }
    319  1.1  mrg 
    320  1.1  mrg /* Return whether a signed modulo by a power of 2 is cheap in MODE
    321  1.1  mrg    when optimizing for SPEED.  */
    322  1.1  mrg 
    323  1.1  mrg static inline bool
    324  1.3  mrg smod_pow2_cheap (bool speed, machine_mode mode)
    325  1.1  mrg {
    326  1.1  mrg   return *smod_pow2_cheap_ptr (speed, mode);
    327  1.1  mrg }
    328  1.1  mrg 
    329  1.1  mrg /* Subroutine of {set_,}zero_cost.  Not to be used otherwise.  */
    330  1.1  mrg 
    331  1.1  mrg static inline int *
    332  1.1  mrg zero_cost_ptr (bool speed)
    333  1.1  mrg {
    334  1.1  mrg   return &this_target_expmed->x_zero_cost[speed];
    335  1.1  mrg }
    336  1.1  mrg 
    337  1.1  mrg /* Set the COST of loading zero when optimizing for SPEED.  */
    338  1.1  mrg 
    339  1.1  mrg static inline void
    340  1.1  mrg set_zero_cost (bool speed, int cost)
    341  1.1  mrg {
    342  1.1  mrg   *zero_cost_ptr (speed) = cost;
    343  1.1  mrg }
    344  1.1  mrg 
    345  1.1  mrg /* Return the COST of loading zero when optimizing for SPEED.  */
    346  1.1  mrg 
    347  1.1  mrg static inline int
    348  1.1  mrg zero_cost (bool speed)
    349  1.1  mrg {
    350  1.1  mrg   return *zero_cost_ptr (speed);
    351  1.1  mrg }
    352  1.1  mrg 
    353  1.1  mrg /* Subroutine of {set_,}add_cost.  Not to be used otherwise.  */
    354  1.1  mrg 
    355  1.1  mrg static inline int *
    356  1.3  mrg add_cost_ptr (bool speed, machine_mode mode)
    357  1.1  mrg {
    358  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_add_cost, speed, mode);
    359  1.1  mrg }
    360  1.1  mrg 
    361  1.1  mrg /* Set the COST of computing an add in MODE when optimizing for SPEED.  */
    362  1.1  mrg 
    363  1.1  mrg static inline void
    364  1.3  mrg set_add_cost (bool speed, machine_mode mode, int cost)
    365  1.1  mrg {
    366  1.1  mrg   *add_cost_ptr (speed, mode) = cost;
    367  1.1  mrg }
    368  1.1  mrg 
    369  1.1  mrg /* Return the cost of computing an add in MODE when optimizing for SPEED.  */
    370  1.1  mrg 
    371  1.1  mrg static inline int
    372  1.3  mrg add_cost (bool speed, machine_mode mode)
    373  1.1  mrg {
    374  1.1  mrg   return *add_cost_ptr (speed, mode);
    375  1.1  mrg }
    376  1.1  mrg 
    377  1.1  mrg /* Subroutine of {set_,}neg_cost.  Not to be used otherwise.  */
    378  1.1  mrg 
    379  1.1  mrg static inline int *
    380  1.3  mrg neg_cost_ptr (bool speed, machine_mode mode)
    381  1.1  mrg {
    382  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_neg_cost, speed, mode);
    383  1.1  mrg }
    384  1.1  mrg 
    385  1.1  mrg /* Set the COST of computing a negation in MODE when optimizing for SPEED.  */
    386  1.1  mrg 
    387  1.1  mrg static inline void
    388  1.3  mrg set_neg_cost (bool speed, machine_mode mode, int cost)
    389  1.1  mrg {
    390  1.1  mrg   *neg_cost_ptr (speed, mode) = cost;
    391  1.1  mrg }
    392  1.1  mrg 
    393  1.1  mrg /* Return the cost of computing a negation in MODE when optimizing for
    394  1.1  mrg    SPEED.  */
    395  1.1  mrg 
    396  1.1  mrg static inline int
    397  1.3  mrg neg_cost (bool speed, machine_mode mode)
    398  1.1  mrg {
    399  1.1  mrg   return *neg_cost_ptr (speed, mode);
    400  1.1  mrg }
    401  1.1  mrg 
    402  1.1  mrg /* Subroutine of {set_,}shift_cost.  Not to be used otherwise.  */
    403  1.1  mrg 
    404  1.1  mrg static inline int *
    405  1.3  mrg shift_cost_ptr (bool speed, machine_mode mode, int bits)
    406  1.1  mrg {
    407  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_shift_cost[bits],
    408  1.1  mrg 			     speed, mode);
    409  1.1  mrg }
    410  1.1  mrg 
    411  1.1  mrg /* Set the COST of doing a shift in MODE by BITS when optimizing for SPEED.  */
    412  1.1  mrg 
    413  1.1  mrg static inline void
    414  1.3  mrg set_shift_cost (bool speed, machine_mode mode, int bits, int cost)
    415  1.1  mrg {
    416  1.1  mrg   *shift_cost_ptr (speed, mode, bits) = cost;
    417  1.1  mrg }
    418  1.1  mrg 
    419  1.1  mrg /* Return the cost of doing a shift in MODE by BITS when optimizing for
    420  1.1  mrg    SPEED.  */
    421  1.1  mrg 
    422  1.1  mrg static inline int
    423  1.3  mrg shift_cost (bool speed, machine_mode mode, int bits)
    424  1.1  mrg {
    425  1.1  mrg   return *shift_cost_ptr (speed, mode, bits);
    426  1.1  mrg }
    427  1.1  mrg 
    428  1.1  mrg /* Subroutine of {set_,}shiftadd_cost.  Not to be used otherwise.  */
    429  1.1  mrg 
    430  1.1  mrg static inline int *
    431  1.3  mrg shiftadd_cost_ptr (bool speed, machine_mode mode, int bits)
    432  1.1  mrg {
    433  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_shiftadd_cost[bits],
    434  1.1  mrg 			     speed, mode);
    435  1.1  mrg }
    436  1.1  mrg 
    437  1.1  mrg /* Set the COST of doing a shift in MODE by BITS followed by an add when
    438  1.1  mrg    optimizing for SPEED.  */
    439  1.1  mrg 
    440  1.1  mrg static inline void
    441  1.3  mrg set_shiftadd_cost (bool speed, machine_mode mode, int bits, int cost)
    442  1.1  mrg {
    443  1.1  mrg   *shiftadd_cost_ptr (speed, mode, bits) = cost;
    444  1.1  mrg }
    445  1.1  mrg 
    446  1.1  mrg /* Return the cost of doing a shift in MODE by BITS followed by an add
    447  1.1  mrg    when optimizing for SPEED.  */
    448  1.1  mrg 
    449  1.1  mrg static inline int
    450  1.3  mrg shiftadd_cost (bool speed, machine_mode mode, int bits)
    451  1.1  mrg {
    452  1.1  mrg   return *shiftadd_cost_ptr (speed, mode, bits);
    453  1.1  mrg }
    454  1.1  mrg 
    455  1.1  mrg /* Subroutine of {set_,}shiftsub0_cost.  Not to be used otherwise.  */
    456  1.1  mrg 
    457  1.1  mrg static inline int *
    458  1.3  mrg shiftsub0_cost_ptr (bool speed, machine_mode mode, int bits)
    459  1.1  mrg {
    460  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_shiftsub0_cost[bits],
    461  1.1  mrg 			     speed, mode);
    462  1.1  mrg }
    463  1.1  mrg 
    464  1.1  mrg /* Set the COST of doing a shift in MODE by BITS and then subtracting a
    465  1.1  mrg    value when optimizing for SPEED.  */
    466  1.1  mrg 
    467  1.1  mrg static inline void
    468  1.3  mrg set_shiftsub0_cost (bool speed, machine_mode mode, int bits, int cost)
    469  1.1  mrg {
    470  1.1  mrg   *shiftsub0_cost_ptr (speed, mode, bits) = cost;
    471  1.1  mrg }
    472  1.1  mrg 
    473  1.1  mrg /* Return the cost of doing a shift in MODE by BITS and then subtracting
    474  1.1  mrg    a value when optimizing for SPEED.  */
    475  1.1  mrg 
    476  1.1  mrg static inline int
    477  1.3  mrg shiftsub0_cost (bool speed, machine_mode mode, int bits)
    478  1.1  mrg {
    479  1.1  mrg   return *shiftsub0_cost_ptr (speed, mode, bits);
    480  1.1  mrg }
    481  1.1  mrg 
    482  1.1  mrg /* Subroutine of {set_,}shiftsub1_cost.  Not to be used otherwise.  */
    483  1.1  mrg 
    484  1.1  mrg static inline int *
    485  1.3  mrg shiftsub1_cost_ptr (bool speed, machine_mode mode, int bits)
    486  1.1  mrg {
    487  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_shiftsub1_cost[bits],
    488  1.1  mrg 			     speed, mode);
    489  1.1  mrg }
    490  1.1  mrg 
    491  1.1  mrg /* Set the COST of subtracting a shift in MODE by BITS from a value when
    492  1.1  mrg    optimizing for SPEED.  */
    493  1.1  mrg 
    494  1.1  mrg static inline void
    495  1.3  mrg set_shiftsub1_cost (bool speed, machine_mode mode, int bits, int cost)
    496  1.1  mrg {
    497  1.1  mrg   *shiftsub1_cost_ptr (speed, mode, bits) = cost;
    498  1.1  mrg }
    499  1.1  mrg 
    500  1.1  mrg /* Return the cost of subtracting a shift in MODE by BITS from a value
    501  1.1  mrg    when optimizing for SPEED.  */
    502  1.1  mrg 
    503  1.1  mrg static inline int
    504  1.3  mrg shiftsub1_cost (bool speed, machine_mode mode, int bits)
    505  1.1  mrg {
    506  1.1  mrg   return *shiftsub1_cost_ptr (speed, mode, bits);
    507  1.1  mrg }
    508  1.1  mrg 
    509  1.1  mrg /* Subroutine of {set_,}mul_cost.  Not to be used otherwise.  */
    510  1.1  mrg 
    511  1.1  mrg static inline int *
    512  1.3  mrg mul_cost_ptr (bool speed, machine_mode mode)
    513  1.1  mrg {
    514  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_mul_cost, speed, mode);
    515  1.1  mrg }
    516  1.1  mrg 
    517  1.1  mrg /* Set the COST of doing a multiplication in MODE when optimizing for
    518  1.1  mrg    SPEED.  */
    519  1.1  mrg 
    520  1.1  mrg static inline void
    521  1.3  mrg set_mul_cost (bool speed, machine_mode mode, int cost)
    522  1.1  mrg {
    523  1.1  mrg   *mul_cost_ptr (speed, mode) = cost;
    524  1.1  mrg }
    525  1.1  mrg 
    526  1.1  mrg /* Return the cost of doing a multiplication in MODE when optimizing
    527  1.1  mrg    for SPEED.  */
    528  1.1  mrg 
    529  1.1  mrg static inline int
    530  1.3  mrg mul_cost (bool speed, machine_mode mode)
    531  1.1  mrg {
    532  1.1  mrg   return *mul_cost_ptr (speed, mode);
    533  1.1  mrg }
    534  1.1  mrg 
    535  1.1  mrg /* Subroutine of {set_,}sdiv_cost.  Not to be used otherwise.  */
    536  1.1  mrg 
    537  1.1  mrg static inline int *
    538  1.3  mrg sdiv_cost_ptr (bool speed, machine_mode mode)
    539  1.1  mrg {
    540  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_sdiv_cost, speed, mode);
    541  1.1  mrg }
    542  1.1  mrg 
    543  1.1  mrg /* Set the COST of doing a signed division in MODE when optimizing
    544  1.1  mrg    for SPEED.  */
    545  1.1  mrg 
    546  1.1  mrg static inline void
    547  1.3  mrg set_sdiv_cost (bool speed, machine_mode mode, int cost)
    548  1.1  mrg {
    549  1.1  mrg   *sdiv_cost_ptr (speed, mode) = cost;
    550  1.1  mrg }
    551  1.1  mrg 
    552  1.1  mrg /* Return the cost of doing a signed division in MODE when optimizing
    553  1.1  mrg    for SPEED.  */
    554  1.1  mrg 
    555  1.1  mrg static inline int
    556  1.3  mrg sdiv_cost (bool speed, machine_mode mode)
    557  1.1  mrg {
    558  1.1  mrg   return *sdiv_cost_ptr (speed, mode);
    559  1.1  mrg }
    560  1.1  mrg 
    561  1.1  mrg /* Subroutine of {set_,}udiv_cost.  Not to be used otherwise.  */
    562  1.1  mrg 
    563  1.1  mrg static inline int *
    564  1.3  mrg udiv_cost_ptr (bool speed, machine_mode mode)
    565  1.1  mrg {
    566  1.1  mrg   return expmed_op_cost_ptr (&this_target_expmed->x_udiv_cost, speed, mode);
    567  1.1  mrg }
    568  1.1  mrg 
    569  1.1  mrg /* Set the COST of doing an unsigned division in MODE when optimizing
    570  1.1  mrg    for SPEED.  */
    571  1.1  mrg 
    572  1.1  mrg static inline void
    573  1.3  mrg set_udiv_cost (bool speed, machine_mode mode, int cost)
    574  1.1  mrg {
    575  1.1  mrg   *udiv_cost_ptr (speed, mode) = cost;
    576  1.1  mrg }
    577  1.1  mrg 
    578  1.1  mrg /* Return the cost of doing an unsigned division in MODE when
    579  1.1  mrg    optimizing for SPEED.  */
    580  1.1  mrg 
    581  1.1  mrg static inline int
    582  1.3  mrg udiv_cost (bool speed, machine_mode mode)
    583  1.1  mrg {
    584  1.1  mrg   return *udiv_cost_ptr (speed, mode);
    585  1.1  mrg }
    586  1.1  mrg 
    587  1.1  mrg /* Subroutine of {set_,}mul_widen_cost.  Not to be used otherwise.  */
    588  1.1  mrg 
    589  1.1  mrg static inline int *
    590  1.3  mrg mul_widen_cost_ptr (bool speed, machine_mode mode)
    591  1.1  mrg {
    592  1.1  mrg   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
    593  1.1  mrg 
    594  1.1  mrg   return &this_target_expmed->x_mul_widen_cost[speed][mode - MIN_MODE_INT];
    595  1.1  mrg }
    596  1.1  mrg 
    597  1.1  mrg /* Set the COST for computing a widening multiplication in MODE when
    598  1.1  mrg    optimizing for SPEED.  */
    599  1.1  mrg 
    600  1.1  mrg static inline void
    601  1.3  mrg set_mul_widen_cost (bool speed, machine_mode mode, int cost)
    602  1.1  mrg {
    603  1.1  mrg   *mul_widen_cost_ptr (speed, mode) = cost;
    604  1.1  mrg }
    605  1.1  mrg 
    606  1.1  mrg /* Return the cost for computing a widening multiplication in MODE when
    607  1.1  mrg    optimizing for SPEED.  */
    608  1.1  mrg 
    609  1.1  mrg static inline int
    610  1.3  mrg mul_widen_cost (bool speed, machine_mode mode)
    611  1.1  mrg {
    612  1.1  mrg   return *mul_widen_cost_ptr (speed, mode);
    613  1.1  mrg }
    614  1.1  mrg 
    615  1.1  mrg /* Subroutine of {set_,}mul_highpart_cost.  Not to be used otherwise.  */
    616  1.1  mrg 
    617  1.1  mrg static inline int *
    618  1.3  mrg mul_highpart_cost_ptr (bool speed, machine_mode mode)
    619  1.1  mrg {
    620  1.1  mrg   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
    621  1.6  mrg   int m = mode - MIN_MODE_INT;
    622  1.6  mrg   gcc_assert (m < NUM_MODE_INT);
    623  1.1  mrg 
    624  1.6  mrg   return &this_target_expmed->x_mul_highpart_cost[speed][m];
    625  1.1  mrg }
    626  1.1  mrg 
    627  1.1  mrg /* Set the COST for computing the high part of a multiplication in MODE
    628  1.1  mrg    when optimizing for SPEED.  */
    629  1.1  mrg 
    630  1.1  mrg static inline void
    631  1.3  mrg set_mul_highpart_cost (bool speed, machine_mode mode, int cost)
    632  1.1  mrg {
    633  1.1  mrg   *mul_highpart_cost_ptr (speed, mode) = cost;
    634  1.1  mrg }
    635  1.1  mrg 
    636  1.1  mrg /* Return the cost for computing the high part of a multiplication in MODE
    637  1.1  mrg    when optimizing for SPEED.  */
    638  1.1  mrg 
    639  1.1  mrg static inline int
    640  1.3  mrg mul_highpart_cost (bool speed, machine_mode mode)
    641  1.1  mrg {
    642  1.1  mrg   return *mul_highpart_cost_ptr (speed, mode);
    643  1.1  mrg }
    644  1.1  mrg 
    645  1.1  mrg /* Subroutine of {set_,}convert_cost.  Not to be used otherwise.  */
    646  1.1  mrg 
    647  1.1  mrg static inline int *
    648  1.3  mrg convert_cost_ptr (machine_mode to_mode, machine_mode from_mode,
    649  1.1  mrg 		  bool speed)
    650  1.1  mrg {
    651  1.1  mrg   int to_idx = expmed_mode_index (to_mode);
    652  1.1  mrg   int from_idx = expmed_mode_index (from_mode);
    653  1.1  mrg 
    654  1.1  mrg   gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1));
    655  1.1  mrg   gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1));
    656  1.1  mrg 
    657  1.1  mrg   return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
    658  1.1  mrg }
    659  1.1  mrg 
    660  1.1  mrg /* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
    661  1.1  mrg    for SPEED.  */
    662  1.1  mrg 
    663  1.1  mrg static inline void
    664  1.3  mrg set_convert_cost (machine_mode to_mode, machine_mode from_mode,
    665  1.1  mrg 		  bool speed, int cost)
    666  1.1  mrg {
    667  1.1  mrg   *convert_cost_ptr (to_mode, from_mode, speed) = cost;
    668  1.1  mrg }
    669  1.1  mrg 
    670  1.1  mrg /* Return the cost for converting from FROM_MODE to TO_MODE when optimizing
    671  1.1  mrg    for SPEED.  */
    672  1.1  mrg 
    673  1.1  mrg static inline int
    674  1.3  mrg convert_cost (machine_mode to_mode, machine_mode from_mode,
    675  1.1  mrg 	      bool speed)
    676  1.1  mrg {
    677  1.1  mrg   return *convert_cost_ptr (to_mode, from_mode, speed);
    678  1.1  mrg }
    679  1.1  mrg 
    680  1.3  mrg extern int mult_by_coeff_cost (HOST_WIDE_INT, machine_mode, bool);
    681  1.3  mrg extern rtx emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
    682  1.7  mrg 			machine_mode mode, machine_mode compare_mode,
    683  1.3  mrg 			int unsignedp, rtx x, rtx y, int normalizep,
    684  1.7  mrg 			machine_mode target_mode);
    685  1.3  mrg 
    686  1.3  mrg /* Arguments MODE, RTX: return an rtx for the negation of that value.
    687  1.3  mrg    May emit insns.  */
    688  1.3  mrg extern rtx negate_rtx (machine_mode, rtx);
    689  1.3  mrg 
    690  1.4  mrg /* Arguments MODE, RTX: return an rtx for the flipping of that value.
    691  1.4  mrg    May emit insns.  */
    692  1.7  mrg extern rtx flip_storage_order (machine_mode, rtx);
    693  1.4  mrg 
    694  1.3  mrg /* Expand a logical AND operation.  */
    695  1.3  mrg extern rtx expand_and (machine_mode, rtx, rtx, rtx);
    696  1.3  mrg 
    697  1.3  mrg /* Emit a store-flag operation.  */
    698  1.3  mrg extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, machine_mode,
    699  1.3  mrg 			    int, int);
    700  1.3  mrg 
    701  1.3  mrg /* Like emit_store_flag, but always succeeds.  */
    702  1.3  mrg extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
    703  1.3  mrg 				  machine_mode, int, int);
    704  1.3  mrg 
    705  1.3  mrg /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
    706  1.3  mrg    replace division by D, and put the least significant N bits of the result
    707  1.3  mrg    in *MULTIPLIER_PTR and return the most significant bit.  */
    708  1.3  mrg extern unsigned HOST_WIDE_INT choose_multiplier (unsigned HOST_WIDE_INT, int,
    709  1.3  mrg 						 int, unsigned HOST_WIDE_INT *,
    710  1.3  mrg 						 int *, int *);
    711  1.3  mrg 
    712  1.3  mrg #ifdef TREE_CODE
    713  1.3  mrg extern rtx expand_variable_shift (enum tree_code, machine_mode,
    714  1.3  mrg 				  rtx, tree, rtx, int);
    715  1.7  mrg extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx,
    716  1.7  mrg 			 int);
    717  1.3  mrg extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx,
    718  1.3  mrg 			  rtx, int);
    719  1.1  mrg #endif
    720  1.3  mrg 
    721  1.7  mrg extern void store_bit_field (rtx, poly_uint64, poly_uint64,
    722  1.7  mrg 			     poly_uint64, poly_uint64,
    723  1.4  mrg 			     machine_mode, rtx, bool);
    724  1.7  mrg extern rtx extract_bit_field (rtx, poly_uint64, poly_uint64, int, rtx,
    725  1.7  mrg 			      machine_mode, machine_mode, bool, rtx *);
    726  1.3  mrg extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
    727  1.7  mrg extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int, bool = false);
    728  1.7  mrg extern rtx expand_mult_highpart_adjust (scalar_int_mode, rtx, rtx, rtx,
    729  1.7  mrg 					rtx, int);
    730  1.3  mrg 
    731  1.3  mrg #endif  // EXPMED_H
    732