expmed.h 20 KB

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