expmed.h 21 KB

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