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