expmed.h revision 1.7 1 1.1 mrg /* Target-dependent costs for expmed.c.
2 1.7 mrg Copyright (C) 1987-2018 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_INT \
137 1.1 mrg (MAX_MODE_INT - MIN_MODE_INT + 1)
138 1.1 mrg #define NUM_MODE_PARTIAL_INT \
139 1.7 mrg (MIN_MODE_PARTIAL_INT == E_VOIDmode ? 0 \
140 1.1 mrg : MAX_MODE_PARTIAL_INT - MIN_MODE_PARTIAL_INT + 1)
141 1.1 mrg #define NUM_MODE_VECTOR_INT \
142 1.7 mrg (MIN_MODE_VECTOR_INT == E_VOIDmode ? 0 \
143 1.1 mrg : MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1)
144 1.1 mrg
145 1.1 mrg #define NUM_MODE_IP_INT (NUM_MODE_INT + NUM_MODE_PARTIAL_INT)
146 1.1 mrg #define NUM_MODE_IPV_INT (NUM_MODE_IP_INT + NUM_MODE_VECTOR_INT)
147 1.1 mrg
148 1.1 mrg struct expmed_op_cheap {
149 1.1 mrg bool cheap[2][NUM_MODE_IPV_INT];
150 1.1 mrg };
151 1.1 mrg
152 1.1 mrg struct expmed_op_costs {
153 1.1 mrg int cost[2][NUM_MODE_IPV_INT];
154 1.1 mrg };
155 1.1 mrg
156 1.1 mrg /* Target-dependent globals. */
157 1.1 mrg struct target_expmed {
158 1.1 mrg /* Each entry of ALG_HASH caches alg_code for some integer. This is
159 1.1 mrg actually a hash table. If we have a collision, that the older
160 1.1 mrg entry is kicked out. */
161 1.1 mrg struct alg_hash_entry x_alg_hash[NUM_ALG_HASH_ENTRIES];
162 1.1 mrg
163 1.1 mrg /* True if x_alg_hash might already have been used. */
164 1.1 mrg bool x_alg_hash_used_p;
165 1.1 mrg
166 1.1 mrg /* Nonzero means divides or modulus operations are relatively cheap for
167 1.1 mrg powers of two, so don't use branches; emit the operation instead.
168 1.1 mrg Usually, this will mean that the MD file will emit non-branch
169 1.1 mrg sequences. */
170 1.1 mrg struct expmed_op_cheap x_sdiv_pow2_cheap;
171 1.1 mrg struct expmed_op_cheap x_smod_pow2_cheap;
172 1.1 mrg
173 1.1 mrg /* Cost of various pieces of RTL. Note that some of these are indexed by
174 1.1 mrg shift count and some by mode. */
175 1.1 mrg int x_zero_cost[2];
176 1.1 mrg struct expmed_op_costs x_add_cost;
177 1.1 mrg struct expmed_op_costs x_neg_cost;
178 1.1 mrg struct expmed_op_costs x_shift_cost[MAX_BITS_PER_WORD];
179 1.1 mrg struct expmed_op_costs x_shiftadd_cost[MAX_BITS_PER_WORD];
180 1.1 mrg struct expmed_op_costs x_shiftsub0_cost[MAX_BITS_PER_WORD];
181 1.1 mrg struct expmed_op_costs x_shiftsub1_cost[MAX_BITS_PER_WORD];
182 1.1 mrg struct expmed_op_costs x_mul_cost;
183 1.1 mrg struct expmed_op_costs x_sdiv_cost;
184 1.1 mrg struct expmed_op_costs x_udiv_cost;
185 1.1 mrg int x_mul_widen_cost[2][NUM_MODE_INT];
186 1.1 mrg int x_mul_highpart_cost[2][NUM_MODE_INT];
187 1.1 mrg
188 1.1 mrg /* Conversion costs are only defined between two scalar integer modes
189 1.1 mrg of different sizes. The first machine mode is the destination mode,
190 1.1 mrg and the second is the source mode. */
191 1.1 mrg int x_convert_cost[2][NUM_MODE_IP_INT][NUM_MODE_IP_INT];
192 1.1 mrg };
193 1.1 mrg
194 1.1 mrg extern struct target_expmed default_target_expmed;
195 1.1 mrg #if SWITCHABLE_TARGET
196 1.1 mrg extern struct target_expmed *this_target_expmed;
197 1.1 mrg #else
198 1.1 mrg #define this_target_expmed (&default_target_expmed)
199 1.1 mrg #endif
200 1.1 mrg
201 1.1 mrg /* Return a pointer to the alg_hash_entry at IDX. */
202 1.1 mrg
203 1.1 mrg static inline struct alg_hash_entry *
204 1.1 mrg alg_hash_entry_ptr (int idx)
205 1.1 mrg {
206 1.1 mrg return &this_target_expmed->x_alg_hash[idx];
207 1.1 mrg }
208 1.1 mrg
209 1.1 mrg /* Return true if the x_alg_hash field might have been used. */
210 1.1 mrg
211 1.1 mrg static inline bool
212 1.1 mrg alg_hash_used_p (void)
213 1.1 mrg {
214 1.1 mrg return this_target_expmed->x_alg_hash_used_p;
215 1.1 mrg }
216 1.1 mrg
217 1.1 mrg /* Set whether the x_alg_hash field might have been used. */
218 1.1 mrg
219 1.1 mrg static inline void
220 1.1 mrg set_alg_hash_used_p (bool usedp)
221 1.1 mrg {
222 1.1 mrg this_target_expmed->x_alg_hash_used_p = usedp;
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg /* Compute an index into the cost arrays by mode class. */
226 1.1 mrg
227 1.1 mrg static inline int
228 1.3 mrg expmed_mode_index (machine_mode mode)
229 1.1 mrg {
230 1.1 mrg switch (GET_MODE_CLASS (mode))
231 1.1 mrg {
232 1.1 mrg case MODE_INT:
233 1.1 mrg return mode - MIN_MODE_INT;
234 1.1 mrg case MODE_PARTIAL_INT:
235 1.3 mrg /* If there are no partial integer modes, help the compiler
236 1.3 mrg to figure out this will never happen. See PR59934. */
237 1.3 mrg if (MIN_MODE_PARTIAL_INT != VOIDmode)
238 1.3 mrg return mode - MIN_MODE_PARTIAL_INT + NUM_MODE_INT;
239 1.3 mrg break;
240 1.1 mrg case MODE_VECTOR_INT:
241 1.3 mrg /* If there are no vector integer modes, help the compiler
242 1.3 mrg to figure out this will never happen. See PR59934. */
243 1.3 mrg if (MIN_MODE_VECTOR_INT != VOIDmode)
244 1.3 mrg return mode - MIN_MODE_VECTOR_INT + NUM_MODE_IP_INT;
245 1.3 mrg break;
246 1.1 mrg default:
247 1.3 mrg break;
248 1.1 mrg }
249 1.3 mrg gcc_unreachable ();
250 1.1 mrg }
251 1.1 mrg
252 1.1 mrg /* Return a pointer to a boolean contained in EOC indicating whether
253 1.1 mrg a particular operation performed in MODE is cheap when optimizing
254 1.1 mrg for SPEED. */
255 1.1 mrg
256 1.1 mrg static inline bool *
257 1.1 mrg expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed,
258 1.3 mrg machine_mode mode)
259 1.1 mrg {
260 1.1 mrg int idx = expmed_mode_index (mode);
261 1.1 mrg return &eoc->cheap[speed][idx];
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg /* Return a pointer to a cost contained in COSTS when a particular
265 1.1 mrg operation is performed in MODE when optimizing for SPEED. */
266 1.1 mrg
267 1.1 mrg static inline int *
268 1.1 mrg expmed_op_cost_ptr (struct expmed_op_costs *costs, bool speed,
269 1.3 mrg machine_mode mode)
270 1.1 mrg {
271 1.1 mrg int idx = expmed_mode_index (mode);
272 1.1 mrg return &costs->cost[speed][idx];
273 1.1 mrg }
274 1.1 mrg
275 1.1 mrg /* Subroutine of {set_,}sdiv_pow2_cheap. Not to be used otherwise. */
276 1.1 mrg
277 1.1 mrg static inline bool *
278 1.3 mrg sdiv_pow2_cheap_ptr (bool speed, machine_mode mode)
279 1.1 mrg {
280 1.1 mrg return expmed_op_cheap_ptr (&this_target_expmed->x_sdiv_pow2_cheap,
281 1.1 mrg speed, mode);
282 1.1 mrg }
283 1.1 mrg
284 1.1 mrg /* Set 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 void
288 1.3 mrg set_sdiv_pow2_cheap (bool speed, machine_mode mode, bool cheap_p)
289 1.1 mrg {
290 1.1 mrg *sdiv_pow2_cheap_ptr (speed, mode) = cheap_p;
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg /* Return whether a signed division by a power of 2 is cheap in MODE
294 1.1 mrg when optimizing for SPEED. */
295 1.1 mrg
296 1.1 mrg static inline bool
297 1.3 mrg sdiv_pow2_cheap (bool speed, machine_mode mode)
298 1.1 mrg {
299 1.1 mrg return *sdiv_pow2_cheap_ptr (speed, mode);
300 1.1 mrg }
301 1.1 mrg
302 1.1 mrg /* Subroutine of {set_,}smod_pow2_cheap. Not to be used otherwise. */
303 1.1 mrg
304 1.1 mrg static inline bool *
305 1.3 mrg smod_pow2_cheap_ptr (bool speed, machine_mode mode)
306 1.1 mrg {
307 1.1 mrg return expmed_op_cheap_ptr (&this_target_expmed->x_smod_pow2_cheap,
308 1.1 mrg speed, mode);
309 1.1 mrg }
310 1.1 mrg
311 1.1 mrg /* Set whether a signed modulo by a power of 2 is CHEAP in MODE when
312 1.1 mrg optimizing for SPEED. */
313 1.1 mrg
314 1.1 mrg static inline void
315 1.3 mrg set_smod_pow2_cheap (bool speed, machine_mode mode, bool cheap)
316 1.1 mrg {
317 1.1 mrg *smod_pow2_cheap_ptr (speed, mode) = cheap;
318 1.1 mrg }
319 1.1 mrg
320 1.1 mrg /* Return whether a signed modulo by a power of 2 is cheap in MODE
321 1.1 mrg when optimizing for SPEED. */
322 1.1 mrg
323 1.1 mrg static inline bool
324 1.3 mrg smod_pow2_cheap (bool speed, machine_mode mode)
325 1.1 mrg {
326 1.1 mrg return *smod_pow2_cheap_ptr (speed, mode);
327 1.1 mrg }
328 1.1 mrg
329 1.1 mrg /* Subroutine of {set_,}zero_cost. Not to be used otherwise. */
330 1.1 mrg
331 1.1 mrg static inline int *
332 1.1 mrg zero_cost_ptr (bool speed)
333 1.1 mrg {
334 1.1 mrg return &this_target_expmed->x_zero_cost[speed];
335 1.1 mrg }
336 1.1 mrg
337 1.1 mrg /* Set the COST of loading zero when optimizing for SPEED. */
338 1.1 mrg
339 1.1 mrg static inline void
340 1.1 mrg set_zero_cost (bool speed, int cost)
341 1.1 mrg {
342 1.1 mrg *zero_cost_ptr (speed) = cost;
343 1.1 mrg }
344 1.1 mrg
345 1.1 mrg /* Return the COST of loading zero when optimizing for SPEED. */
346 1.1 mrg
347 1.1 mrg static inline int
348 1.1 mrg zero_cost (bool speed)
349 1.1 mrg {
350 1.1 mrg return *zero_cost_ptr (speed);
351 1.1 mrg }
352 1.1 mrg
353 1.1 mrg /* Subroutine of {set_,}add_cost. Not to be used otherwise. */
354 1.1 mrg
355 1.1 mrg static inline int *
356 1.3 mrg add_cost_ptr (bool speed, machine_mode mode)
357 1.1 mrg {
358 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_add_cost, speed, mode);
359 1.1 mrg }
360 1.1 mrg
361 1.1 mrg /* Set the COST of computing an add in MODE when optimizing for SPEED. */
362 1.1 mrg
363 1.1 mrg static inline void
364 1.3 mrg set_add_cost (bool speed, machine_mode mode, int cost)
365 1.1 mrg {
366 1.1 mrg *add_cost_ptr (speed, mode) = cost;
367 1.1 mrg }
368 1.1 mrg
369 1.1 mrg /* Return the cost of computing an add in MODE when optimizing for SPEED. */
370 1.1 mrg
371 1.1 mrg static inline int
372 1.3 mrg add_cost (bool speed, machine_mode mode)
373 1.1 mrg {
374 1.1 mrg return *add_cost_ptr (speed, mode);
375 1.1 mrg }
376 1.1 mrg
377 1.1 mrg /* Subroutine of {set_,}neg_cost. Not to be used otherwise. */
378 1.1 mrg
379 1.1 mrg static inline int *
380 1.3 mrg neg_cost_ptr (bool speed, machine_mode mode)
381 1.1 mrg {
382 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_neg_cost, speed, mode);
383 1.1 mrg }
384 1.1 mrg
385 1.1 mrg /* Set the COST of computing a negation in MODE when optimizing for SPEED. */
386 1.1 mrg
387 1.1 mrg static inline void
388 1.3 mrg set_neg_cost (bool speed, machine_mode mode, int cost)
389 1.1 mrg {
390 1.1 mrg *neg_cost_ptr (speed, mode) = cost;
391 1.1 mrg }
392 1.1 mrg
393 1.1 mrg /* Return the cost of computing a negation in MODE when optimizing for
394 1.1 mrg SPEED. */
395 1.1 mrg
396 1.1 mrg static inline int
397 1.3 mrg neg_cost (bool speed, machine_mode mode)
398 1.1 mrg {
399 1.1 mrg return *neg_cost_ptr (speed, mode);
400 1.1 mrg }
401 1.1 mrg
402 1.1 mrg /* Subroutine of {set_,}shift_cost. Not to be used otherwise. */
403 1.1 mrg
404 1.1 mrg static inline int *
405 1.3 mrg shift_cost_ptr (bool speed, machine_mode mode, int bits)
406 1.1 mrg {
407 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_shift_cost[bits],
408 1.1 mrg speed, mode);
409 1.1 mrg }
410 1.1 mrg
411 1.1 mrg /* Set the COST of doing a shift in MODE by BITS when optimizing for SPEED. */
412 1.1 mrg
413 1.1 mrg static inline void
414 1.3 mrg set_shift_cost (bool speed, machine_mode mode, int bits, int cost)
415 1.1 mrg {
416 1.1 mrg *shift_cost_ptr (speed, mode, bits) = cost;
417 1.1 mrg }
418 1.1 mrg
419 1.1 mrg /* Return the cost of doing a shift in MODE by BITS when optimizing for
420 1.1 mrg SPEED. */
421 1.1 mrg
422 1.1 mrg static inline int
423 1.3 mrg shift_cost (bool speed, machine_mode mode, int bits)
424 1.1 mrg {
425 1.1 mrg return *shift_cost_ptr (speed, mode, bits);
426 1.1 mrg }
427 1.1 mrg
428 1.1 mrg /* Subroutine of {set_,}shiftadd_cost. Not to be used otherwise. */
429 1.1 mrg
430 1.1 mrg static inline int *
431 1.3 mrg shiftadd_cost_ptr (bool speed, machine_mode mode, int bits)
432 1.1 mrg {
433 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_shiftadd_cost[bits],
434 1.1 mrg speed, mode);
435 1.1 mrg }
436 1.1 mrg
437 1.1 mrg /* Set the COST of doing a shift in MODE by BITS followed by an add when
438 1.1 mrg optimizing for SPEED. */
439 1.1 mrg
440 1.1 mrg static inline void
441 1.3 mrg set_shiftadd_cost (bool speed, machine_mode mode, int bits, int cost)
442 1.1 mrg {
443 1.1 mrg *shiftadd_cost_ptr (speed, mode, bits) = cost;
444 1.1 mrg }
445 1.1 mrg
446 1.1 mrg /* Return the cost of doing a shift in MODE by BITS followed by an add
447 1.1 mrg when optimizing for SPEED. */
448 1.1 mrg
449 1.1 mrg static inline int
450 1.3 mrg shiftadd_cost (bool speed, machine_mode mode, int bits)
451 1.1 mrg {
452 1.1 mrg return *shiftadd_cost_ptr (speed, mode, bits);
453 1.1 mrg }
454 1.1 mrg
455 1.1 mrg /* Subroutine of {set_,}shiftsub0_cost. Not to be used otherwise. */
456 1.1 mrg
457 1.1 mrg static inline int *
458 1.3 mrg shiftsub0_cost_ptr (bool speed, machine_mode mode, int bits)
459 1.1 mrg {
460 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_shiftsub0_cost[bits],
461 1.1 mrg speed, mode);
462 1.1 mrg }
463 1.1 mrg
464 1.1 mrg /* Set the COST of doing a shift in MODE by BITS and then subtracting a
465 1.1 mrg value when optimizing for SPEED. */
466 1.1 mrg
467 1.1 mrg static inline void
468 1.3 mrg set_shiftsub0_cost (bool speed, machine_mode mode, int bits, int cost)
469 1.1 mrg {
470 1.1 mrg *shiftsub0_cost_ptr (speed, mode, bits) = cost;
471 1.1 mrg }
472 1.1 mrg
473 1.1 mrg /* Return the cost of doing a shift in MODE by BITS and then subtracting
474 1.1 mrg a value when optimizing for SPEED. */
475 1.1 mrg
476 1.1 mrg static inline int
477 1.3 mrg shiftsub0_cost (bool speed, machine_mode mode, int bits)
478 1.1 mrg {
479 1.1 mrg return *shiftsub0_cost_ptr (speed, mode, bits);
480 1.1 mrg }
481 1.1 mrg
482 1.1 mrg /* Subroutine of {set_,}shiftsub1_cost. Not to be used otherwise. */
483 1.1 mrg
484 1.1 mrg static inline int *
485 1.3 mrg shiftsub1_cost_ptr (bool speed, machine_mode mode, int bits)
486 1.1 mrg {
487 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_shiftsub1_cost[bits],
488 1.1 mrg speed, mode);
489 1.1 mrg }
490 1.1 mrg
491 1.1 mrg /* Set the COST of subtracting a shift in MODE by BITS from a value when
492 1.1 mrg optimizing for SPEED. */
493 1.1 mrg
494 1.1 mrg static inline void
495 1.3 mrg set_shiftsub1_cost (bool speed, machine_mode mode, int bits, int cost)
496 1.1 mrg {
497 1.1 mrg *shiftsub1_cost_ptr (speed, mode, bits) = cost;
498 1.1 mrg }
499 1.1 mrg
500 1.1 mrg /* Return the cost of subtracting a shift in MODE by BITS from a value
501 1.1 mrg when optimizing for SPEED. */
502 1.1 mrg
503 1.1 mrg static inline int
504 1.3 mrg shiftsub1_cost (bool speed, machine_mode mode, int bits)
505 1.1 mrg {
506 1.1 mrg return *shiftsub1_cost_ptr (speed, mode, bits);
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg /* Subroutine of {set_,}mul_cost. Not to be used otherwise. */
510 1.1 mrg
511 1.1 mrg static inline int *
512 1.3 mrg mul_cost_ptr (bool speed, machine_mode mode)
513 1.1 mrg {
514 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_mul_cost, speed, mode);
515 1.1 mrg }
516 1.1 mrg
517 1.1 mrg /* Set the COST of doing a multiplication in MODE when optimizing for
518 1.1 mrg SPEED. */
519 1.1 mrg
520 1.1 mrg static inline void
521 1.3 mrg set_mul_cost (bool speed, machine_mode mode, int cost)
522 1.1 mrg {
523 1.1 mrg *mul_cost_ptr (speed, mode) = cost;
524 1.1 mrg }
525 1.1 mrg
526 1.1 mrg /* Return the cost of doing a multiplication in MODE when optimizing
527 1.1 mrg for SPEED. */
528 1.1 mrg
529 1.1 mrg static inline int
530 1.3 mrg mul_cost (bool speed, machine_mode mode)
531 1.1 mrg {
532 1.1 mrg return *mul_cost_ptr (speed, mode);
533 1.1 mrg }
534 1.1 mrg
535 1.1 mrg /* Subroutine of {set_,}sdiv_cost. Not to be used otherwise. */
536 1.1 mrg
537 1.1 mrg static inline int *
538 1.3 mrg sdiv_cost_ptr (bool speed, machine_mode mode)
539 1.1 mrg {
540 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_sdiv_cost, speed, mode);
541 1.1 mrg }
542 1.1 mrg
543 1.1 mrg /* Set 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 void
547 1.3 mrg set_sdiv_cost (bool speed, machine_mode mode, int cost)
548 1.1 mrg {
549 1.1 mrg *sdiv_cost_ptr (speed, mode) = cost;
550 1.1 mrg }
551 1.1 mrg
552 1.1 mrg /* Return the cost of doing a signed division in MODE when optimizing
553 1.1 mrg for SPEED. */
554 1.1 mrg
555 1.1 mrg static inline int
556 1.3 mrg sdiv_cost (bool speed, machine_mode mode)
557 1.1 mrg {
558 1.1 mrg return *sdiv_cost_ptr (speed, mode);
559 1.1 mrg }
560 1.1 mrg
561 1.1 mrg /* Subroutine of {set_,}udiv_cost. Not to be used otherwise. */
562 1.1 mrg
563 1.1 mrg static inline int *
564 1.3 mrg udiv_cost_ptr (bool speed, machine_mode mode)
565 1.1 mrg {
566 1.1 mrg return expmed_op_cost_ptr (&this_target_expmed->x_udiv_cost, speed, mode);
567 1.1 mrg }
568 1.1 mrg
569 1.1 mrg /* Set the COST of doing an unsigned division in MODE when optimizing
570 1.1 mrg for SPEED. */
571 1.1 mrg
572 1.1 mrg static inline void
573 1.3 mrg set_udiv_cost (bool speed, machine_mode mode, int cost)
574 1.1 mrg {
575 1.1 mrg *udiv_cost_ptr (speed, mode) = cost;
576 1.1 mrg }
577 1.1 mrg
578 1.1 mrg /* Return the cost of doing an unsigned division in MODE when
579 1.1 mrg optimizing for SPEED. */
580 1.1 mrg
581 1.1 mrg static inline int
582 1.3 mrg udiv_cost (bool speed, machine_mode mode)
583 1.1 mrg {
584 1.1 mrg return *udiv_cost_ptr (speed, mode);
585 1.1 mrg }
586 1.1 mrg
587 1.1 mrg /* Subroutine of {set_,}mul_widen_cost. Not to be used otherwise. */
588 1.1 mrg
589 1.1 mrg static inline int *
590 1.3 mrg mul_widen_cost_ptr (bool speed, machine_mode mode)
591 1.1 mrg {
592 1.1 mrg gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
593 1.1 mrg
594 1.1 mrg return &this_target_expmed->x_mul_widen_cost[speed][mode - MIN_MODE_INT];
595 1.1 mrg }
596 1.1 mrg
597 1.1 mrg /* Set 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 void
601 1.3 mrg set_mul_widen_cost (bool speed, machine_mode mode, int cost)
602 1.1 mrg {
603 1.1 mrg *mul_widen_cost_ptr (speed, mode) = cost;
604 1.1 mrg }
605 1.1 mrg
606 1.1 mrg /* Return the cost for computing a widening multiplication in MODE when
607 1.1 mrg optimizing for SPEED. */
608 1.1 mrg
609 1.1 mrg static inline int
610 1.3 mrg mul_widen_cost (bool speed, machine_mode mode)
611 1.1 mrg {
612 1.1 mrg return *mul_widen_cost_ptr (speed, mode);
613 1.1 mrg }
614 1.1 mrg
615 1.1 mrg /* Subroutine of {set_,}mul_highpart_cost. Not to be used otherwise. */
616 1.1 mrg
617 1.1 mrg static inline int *
618 1.3 mrg mul_highpart_cost_ptr (bool speed, machine_mode mode)
619 1.1 mrg {
620 1.1 mrg gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
621 1.6 mrg int m = mode - MIN_MODE_INT;
622 1.6 mrg gcc_assert (m < NUM_MODE_INT);
623 1.1 mrg
624 1.6 mrg return &this_target_expmed->x_mul_highpart_cost[speed][m];
625 1.1 mrg }
626 1.1 mrg
627 1.1 mrg /* Set 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 void
631 1.3 mrg set_mul_highpart_cost (bool speed, machine_mode mode, int cost)
632 1.1 mrg {
633 1.1 mrg *mul_highpart_cost_ptr (speed, mode) = cost;
634 1.1 mrg }
635 1.1 mrg
636 1.1 mrg /* Return the cost for computing the high part of a multiplication in MODE
637 1.1 mrg when optimizing for SPEED. */
638 1.1 mrg
639 1.1 mrg static inline int
640 1.3 mrg mul_highpart_cost (bool speed, machine_mode mode)
641 1.1 mrg {
642 1.1 mrg return *mul_highpart_cost_ptr (speed, mode);
643 1.1 mrg }
644 1.1 mrg
645 1.1 mrg /* Subroutine of {set_,}convert_cost. Not to be used otherwise. */
646 1.1 mrg
647 1.1 mrg static inline int *
648 1.3 mrg convert_cost_ptr (machine_mode to_mode, machine_mode from_mode,
649 1.1 mrg bool speed)
650 1.1 mrg {
651 1.1 mrg int to_idx = expmed_mode_index (to_mode);
652 1.1 mrg int from_idx = expmed_mode_index (from_mode);
653 1.1 mrg
654 1.1 mrg gcc_assert (IN_RANGE (to_idx, 0, NUM_MODE_IP_INT - 1));
655 1.1 mrg gcc_assert (IN_RANGE (from_idx, 0, NUM_MODE_IP_INT - 1));
656 1.1 mrg
657 1.1 mrg return &this_target_expmed->x_convert_cost[speed][to_idx][from_idx];
658 1.1 mrg }
659 1.1 mrg
660 1.1 mrg /* Set the COST for converting from FROM_MODE to TO_MODE when optimizing
661 1.1 mrg for SPEED. */
662 1.1 mrg
663 1.1 mrg static inline void
664 1.3 mrg set_convert_cost (machine_mode to_mode, machine_mode from_mode,
665 1.1 mrg bool speed, int cost)
666 1.1 mrg {
667 1.1 mrg *convert_cost_ptr (to_mode, from_mode, speed) = cost;
668 1.1 mrg }
669 1.1 mrg
670 1.1 mrg /* Return the cost for converting from FROM_MODE to TO_MODE when optimizing
671 1.1 mrg for SPEED. */
672 1.1 mrg
673 1.1 mrg static inline int
674 1.3 mrg convert_cost (machine_mode to_mode, machine_mode from_mode,
675 1.1 mrg bool speed)
676 1.1 mrg {
677 1.1 mrg return *convert_cost_ptr (to_mode, from_mode, speed);
678 1.1 mrg }
679 1.1 mrg
680 1.3 mrg extern int mult_by_coeff_cost (HOST_WIDE_INT, machine_mode, bool);
681 1.3 mrg extern rtx emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
682 1.7 mrg machine_mode mode, machine_mode compare_mode,
683 1.3 mrg int unsignedp, rtx x, rtx y, int normalizep,
684 1.7 mrg machine_mode target_mode);
685 1.3 mrg
686 1.3 mrg /* Arguments MODE, RTX: return an rtx for the negation of that value.
687 1.3 mrg May emit insns. */
688 1.3 mrg extern rtx negate_rtx (machine_mode, rtx);
689 1.3 mrg
690 1.4 mrg /* Arguments MODE, RTX: return an rtx for the flipping of that value.
691 1.4 mrg May emit insns. */
692 1.7 mrg extern rtx flip_storage_order (machine_mode, rtx);
693 1.4 mrg
694 1.3 mrg /* Expand a logical AND operation. */
695 1.3 mrg extern rtx expand_and (machine_mode, rtx, rtx, rtx);
696 1.3 mrg
697 1.3 mrg /* Emit a store-flag operation. */
698 1.3 mrg extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, machine_mode,
699 1.3 mrg int, int);
700 1.3 mrg
701 1.3 mrg /* Like emit_store_flag, but always succeeds. */
702 1.3 mrg extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
703 1.3 mrg machine_mode, int, int);
704 1.3 mrg
705 1.3 mrg /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
706 1.3 mrg replace division by D, and put the least significant N bits of the result
707 1.3 mrg in *MULTIPLIER_PTR and return the most significant bit. */
708 1.3 mrg extern unsigned HOST_WIDE_INT choose_multiplier (unsigned HOST_WIDE_INT, int,
709 1.3 mrg int, unsigned HOST_WIDE_INT *,
710 1.3 mrg int *, int *);
711 1.3 mrg
712 1.3 mrg #ifdef TREE_CODE
713 1.3 mrg extern rtx expand_variable_shift (enum tree_code, machine_mode,
714 1.3 mrg rtx, tree, rtx, int);
715 1.7 mrg extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx,
716 1.7 mrg int);
717 1.3 mrg extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx,
718 1.3 mrg rtx, int);
719 1.1 mrg #endif
720 1.3 mrg
721 1.7 mrg extern void store_bit_field (rtx, poly_uint64, poly_uint64,
722 1.7 mrg poly_uint64, poly_uint64,
723 1.4 mrg machine_mode, rtx, bool);
724 1.7 mrg extern rtx extract_bit_field (rtx, poly_uint64, poly_uint64, int, rtx,
725 1.7 mrg machine_mode, machine_mode, bool, rtx *);
726 1.3 mrg extern rtx extract_low_bits (machine_mode, machine_mode, rtx);
727 1.7 mrg extern rtx expand_mult (machine_mode, rtx, rtx, rtx, int, bool = false);
728 1.7 mrg extern rtx expand_mult_highpart_adjust (scalar_int_mode, rtx, rtx, rtx,
729 1.7 mrg rtx, int);
730 1.3 mrg
731 1.3 mrg #endif // EXPMED_H
732