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