Home | History | Annotate | Line # | Download | only in gcc
      1  1.10  mrg /* Target-dependent costs for expmed.cc.
      2  1.10  mrg    Copyright (C) 1987-2022 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_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.6  mrg   int m = mode - MIN_MODE_INT;
    613   1.6  mrg   gcc_assert (m < NUM_MODE_INT);
    614   1.1  mrg 
    615   1.6  mrg   return &this_target_expmed->x_mul_highpart_cost[speed][m];
    616   1.1  mrg }
    617   1.1  mrg 
    618   1.1  mrg /* Set the COST for computing the high part of a multiplication in MODE
    619   1.1  mrg    when optimizing for SPEED.  */
    620   1.1  mrg 
    621   1.1  mrg static inline void
    622   1.3  mrg set_mul_highpart_cost (bool speed, machine_mode mode, int cost)
    623   1.1  mrg {
    624   1.1  mrg   *mul_highpart_cost_ptr (speed, mode) = cost;
    625   1.1  mrg }
    626   1.1  mrg 
    627   1.1  mrg /* Return 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 int
    631   1.3  mrg mul_highpart_cost (bool speed, machine_mode mode)
    632   1.1  mrg {
    633   1.1  mrg   return *mul_highpart_cost_ptr (speed, mode);
    634   1.1  mrg }
    635   1.1  mrg 
    636   1.1  mrg /* Subroutine of {set_,}convert_cost.  Not to be used otherwise.  */
    637   1.1  mrg 
    638   1.1  mrg static inline int *
    639   1.3  mrg convert_cost_ptr (machine_mode to_mode, machine_mode from_mode,
    640   1.1  mrg 		  bool speed)
    641   1.1  mrg {
    642   1.1  mrg   int to_idx = expmed_mode_index (to_mode);
    643   1.1  mrg   int from_idx = expmed_mode_index (from_mode);
    644   1.1  mrg 
    645   1.1  mrg   gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1));
    646   1.1  mrg   gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1));
    647   1.1  mrg 
    648   1.1  mrg   return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
    649   1.1  mrg }
    650   1.1  mrg 
    651   1.1  mrg /* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
    652   1.1  mrg    for SPEED.  */
    653   1.1  mrg 
    654   1.1  mrg static inline void
    655   1.3  mrg set_convert_cost (machine_mode to_mode, machine_mode from_mode,
    656   1.1  mrg 		  bool speed, int cost)
    657   1.1  mrg {
    658   1.1  mrg   *convert_cost_ptr (to_mode, from_mode, speed) = cost;
    659   1.1  mrg }
    660   1.1  mrg 
    661   1.1  mrg /* Return the cost for converting from FROM_MODE to TO_MODE when optimizing
    662   1.1  mrg    for SPEED.  */
    663   1.1  mrg 
    664   1.1  mrg static inline int
    665   1.3  mrg convert_cost (machine_mode to_mode, machine_mode from_mode,
    666   1.1  mrg 	      bool speed)
    667   1.1  mrg {
    668   1.1  mrg   return *convert_cost_ptr (to_mode, from_mode, speed);
    669   1.1  mrg }
    670   1.1  mrg 
    671   1.3  mrg extern int mult_by_coeff_cost (HOST_WIDE_INT, machine_mode, bool);
    672   1.3  mrg extern rtx emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
    673   1.7  mrg 			machine_mode mode, machine_mode compare_mode,
    674   1.3  mrg 			int unsignedp, rtx x, rtx y, int normalizep,
    675   1.7  mrg 			machine_mode target_mode);
    676   1.3  mrg 
    677   1.3  mrg /* Arguments MODE, RTX: return an rtx for the negation of that value.
    678   1.3  mrg    May emit insns.  */
    679   1.3  mrg extern rtx negate_rtx (machine_mode, rtx);
    680   1.3  mrg 
    681   1.4  mrg /* Arguments MODE, RTX: return an rtx for the flipping of that value.
    682   1.4  mrg    May emit insns.  */
    683   1.7  mrg extern rtx flip_storage_order (machine_mode, rtx);
    684   1.4  mrg 
    685   1.3  mrg /* Expand a logical AND operation.  */
    686   1.3  mrg extern rtx expand_and (machine_mode, rtx, rtx, rtx);
    687   1.3  mrg 
    688   1.3  mrg /* Emit a store-flag operation.  */
    689   1.3  mrg extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, machine_mode,
    690   1.3  mrg 			    int, int);
    691   1.3  mrg 
    692   1.3  mrg /* Like emit_store_flag, but always succeeds.  */
    693   1.3  mrg extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
    694   1.3  mrg 				  machine_mode, int, int);
    695   1.3  mrg 
    696   1.8  mrg extern void canonicalize_comparison (machine_mode, enum rtx_code *, rtx *);
    697   1.8  mrg 
    698   1.3  mrg /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
    699   1.3  mrg    replace division by D, and put the least significant N bits of the result
    700   1.3  mrg    in *MULTIPLIER_PTR and return the most significant bit.  */
    701   1.3  mrg extern unsigned HOST_WIDE_INT choose_multiplier (unsigned HOST_WIDE_INT, int,
    702   1.3  mrg 						 int, unsigned HOST_WIDE_INT *,
    703   1.3  mrg 						 int *, int *);
    704   1.3  mrg 
    705   1.3  mrg #ifdef TREE_CODE
    706   1.3  mrg extern rtx expand_variable_shift (enum tree_code, machine_mode,
    707   1.3  mrg 				  rtx, tree, rtx, int);
    708   1.7  mrg extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx,
    709   1.7  mrg 			 int);
    710  1.10  mrg #ifdef GCC_OPTABS_H
    711   1.3  mrg extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx,
    712  1.10  mrg 			  rtx, int, enum optab_methods = OPTAB_LIB_WIDEN);
    713  1.10  mrg #endif
    714   1.1  mrg #endif
    715   1.3  mrg 
    716   1.7  mrg extern void store_bit_field (rtx, poly_uint64, poly_uint64,
    717   1.7  mrg 			     poly_uint64, poly_uint64,
    718   1.4  mrg 			     machine_mode, rtx, bool);
    719   1.7  mrg extern rtx extract_bit_field (rtx, poly_uint64, poly_uint64, int, rtx,
    720   1.7  mrg 			      machine_mode, machine_mode, bool, rtx *);
    721   1.3  mrg extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
    722   1.7  mrg extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int, bool = false);
    723   1.7  mrg extern rtx expand_mult_highpart_adjust (scalar_int_mode, rtx, rtx, rtx,
    724   1.7  mrg 					rtx, int);
    725   1.3  mrg 
    726   1.3  mrg #endif  // EXPMED_H
    727