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