]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/optabs.h
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / optabs.h
CommitLineData
d8fc4d0b 1/* Definitions for code generation pass of GNU compiler.
711789cc 2 Copyright (C) 2001-2013 Free Software Foundation, Inc.
d8fc4d0b 3
049df704 4This file is part of GCC.
d8fc4d0b 5
049df704 6GCC is free software; you can redistribute it and/or modify
d8fc4d0b 7it under the terms of the GNU General Public License as published by
8c4c00c1 8the Free Software Foundation; either version 3, or (at your option)
d8fc4d0b 9any later version.
10
049df704 11GCC is distributed in the hope that it will be useful,
d8fc4d0b 12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
d8fc4d0b 19
20#ifndef GCC_OPTABS_H
21#define GCC_OPTABS_H
22
23#include "insn-codes.h"
ee65118b 24#include "insn-opinit.h"
d8fc4d0b 25
ee65118b 26typedef enum optab_tag optab;
27typedef enum optab_tag convert_optab;
28typedef enum optab_tag direct_optab;
6b8dbb53 29
ee65118b 30struct optab_libcall_d
d8fc4d0b 31{
f36b9f69 32 char libcall_suffix;
b7834994 33 const char *libcall_basename;
ee65118b 34 void (*libcall_gen) (optab, const char *name,
35 char suffix, enum machine_mode);
1f3233d1 36};
d8fc4d0b 37
ee65118b 38struct convert_optab_libcall_d
a7cc195f 39{
f36b9f69 40 const char *libcall_basename;
ee65118b 41 void (*libcall_gen) (convert_optab, const char *name,
42 enum machine_mode, enum machine_mode);
a7cc195f 43};
a7cc195f 44
d8fc4d0b 45/* Given an enum insn_code, access the function to construct
46 the body of that kind of insn. */
a7cc195f 47#define GEN_FCN(CODE) (insn_data[CODE].genfun)
d8fc4d0b 48
ee65118b 49/* Contains the optab used for each rtx code, and vice-versa. */
50extern const optab code_to_optab_[NUM_RTX_CODE];
51extern const enum rtx_code optab_to_code_[NUM_OPTABS];
ebb6e3c1 52
53static inline optab
54code_to_optab (enum rtx_code code)
55{
56 return code_to_optab_[code];
57}
58
ee65118b 59static inline enum rtx_code
60optab_to_code (optab op)
6b531606 61{
ee65118b 62 return optab_to_code_[op];
63}
d8fc4d0b 64
ee65118b 65extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];
66extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];
6b531606 67
ee65118b 68/* Returns the active icode for the given (encoded) optab. */
69extern enum insn_code raw_optab_handler (unsigned);
70extern bool swap_optab_enable (optab, enum machine_mode, bool);
6b531606 71
2770cb33 72/* Target-dependent globals. */
73struct target_optabs {
ee65118b 74 /* Patterns that are used by optabs that are enabled for this target. */
75 bool pat_enable[NUM_OPTAB_PATTERNS];
2770cb33 76};
77
78extern struct target_optabs default_target_optabs;
79#if SWITCHABLE_TARGET
80extern struct target_optabs *this_target_optabs;
81#else
82#define this_target_optabs (&default_target_optabs)
83#endif
2770cb33 84\f
d8fc4d0b 85/* Define functions given in optabs.c. */
86
2c02962c 87extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
4a61a337 88 rtx target, int unsignedp);
89
26364c07 90extern rtx expand_ternary_op (enum machine_mode mode, optab ternary_optab,
91 rtx op0, rtx op1, rtx op2, rtx target,
b056d812 92 int unsignedp);
93
d8fc4d0b 94/* Expand a binary operation given optab and rtx operands. */
3ad4992f 95extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
96 enum optab_methods);
d8fc4d0b 97
4d18c297 98extern rtx simplify_expand_binop (enum machine_mode mode, optab binoptab,
99 rtx op0, rtx op1, rtx target, int unsignedp,
100 enum optab_methods methods);
101
05d18e8b 102extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
103 enum optab_methods);
104
d8fc4d0b 105/* Expand a binary operation with both signed and unsigned forms. */
3ad4992f 106extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx,
107 rtx, int, enum optab_methods);
d8fc4d0b 108
6b43bae4 109/* Generate code to perform an operation on one operand with two results. */
110extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
111
d8fc4d0b 112/* Generate code to perform an operation on two operands with two results. */
3ad4992f 113extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
d8fc4d0b 114
30e9913f 115/* Generate code to perform an operation on two operands with two
116 results, using a library function. */
7d3f6cc7 117extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
30e9913f 118 enum rtx_code);
119
d8fc4d0b 120/* Expand a unary arithmetic operation given optab rtx operand. */
3ad4992f 121extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
d8fc4d0b 122
123/* Expand the absolute value operation. */
3ad4992f 124extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int);
125extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int);
d8fc4d0b 126
94e08e50 127/* Expand the one's complement absolute value operation. */
128extern rtx expand_one_cmpl_abs_nojump (enum machine_mode, rtx, rtx);
129
270436f3 130/* Expand the copysign operation. */
131extern rtx expand_copysign (rtx, rtx, rtx);
132
d8fc4d0b 133/* Generate an instruction with a given INSN_CODE with an output and
134 an input. */
8786db1e 135extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
136extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
d8fc4d0b 137
aff5fb4d 138/* Find a widening optab even if it doesn't widen as much as we want. */
139#define find_widening_optab_handler(A,B,C,D) \
140 find_widening_optab_handler_and_mode (A, B, C, D, NULL)
141extern enum insn_code find_widening_optab_handler_and_mode (optab,
142 enum machine_mode,
143 enum machine_mode,
144 int,
145 enum machine_mode *);
146
4d54df85 147/* An extra flag to control optab_for_tree_code's behavior. This is needed to
148 distinguish between machines with a vector shift that takes a scalar for the
149 shift amount vs. machines that take a vector for the shift amount. */
150enum optab_subtype
151{
152 optab_default,
153 optab_scalar,
154 optab_vector
155};
156
157/* Return the optab used for computing the given operation on the type given by
158 the second argument. The third argument distinguishes between the types of
159 vector shifts and rotates */
160extern optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype);
161
d8fc4d0b 162/* The various uses that a comparison can have; used by can_compare_p:
163 jumps, conditional moves, store flag operations. */
164enum can_compare_purpose
165{
166 ccp_jump,
167 ccp_cmov,
168 ccp_store_flag
169};
170
171/* Nonzero if a compare of mode MODE can be done straightforwardly
172 (without splitting it into pieces). */
3ad4992f 173extern int can_compare_p (enum rtx_code, enum machine_mode,
174 enum can_compare_purpose);
d8fc4d0b 175
d8fc4d0b 176/* Return the INSN_CODE to use for an extend operation. */
3ad4992f 177extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int);
d8fc4d0b 178
179/* Generate the body of an insn to extend Y (with mode MFROM)
180 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3ad4992f 181extern rtx gen_extend_insn (rtx, rtx, enum machine_mode,
182 enum machine_mode, int);
d8fc4d0b 183
f2f543a3 184/* Call this to reset the function entry for one optab. */
185extern void set_optab_libfunc (optab, enum machine_mode, const char *);
a7cc195f 186extern void set_conv_libfunc (convert_optab, enum machine_mode,
187 enum machine_mode, const char *);
f2f543a3 188
29139cdc 189/* Call this to install all of the __sync libcalls up to size MAX. */
190extern void init_sync_libfuncs (int max);
191
68a556d6 192/* Generate code for a FIXED_CONVERT_EXPR. */
193extern void expand_fixed_convert (rtx, rtx, int, int);
194
d8fc4d0b 195/* Generate code for a FLOAT_EXPR. */
3ad4992f 196extern void expand_float (rtx, rtx, int);
d8fc4d0b 197
f0938d2c 198/* Return the insn_code for a FLOAT_EXPR. */
199enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
200
1cd6e20d 201/* Return true if there is an inline compare and swap pattern. */
29139cdc 202extern bool can_compare_and_swap_p (enum machine_mode, bool);
1cd6e20d 203
3ec11c49 204/* Return true if there is an inline atomic exchange pattern. */
205extern bool can_atomic_exchange_p (enum machine_mode, bool);
206
1cd6e20d 207/* Generate code for a compare and swap. */
208extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
209 enum memmodel, enum memmodel);
210
fe54c06b 211/* Generate memory barriers. */
212extern void expand_mem_thread_fence (enum memmodel);
213extern void expand_mem_signal_fence (enum memmodel);
214
b423d9f7 215/* Check whether an operation represented by the code CODE is a
216 convert operation that is supported by the target platform in
217 vector form */
218bool supportable_convert_operation (enum tree_code, tree, tree, tree *,
219 enum tree_code *);
220
d8fc4d0b 221/* Generate code for a FIX_EXPR. */
3ad4992f 222extern void expand_fix (rtx, rtx, int);
d8fc4d0b 223
5f51ee59 224/* Generate code for float to integral conversion. */
225extern bool expand_sfix_optab (rtx, rtx, convert_optab);
226
0ca212b8 227/* Generate code for a widening multiply. */
228extern rtx expand_widening_mult (enum machine_mode, rtx, rtx, rtx, int, optab);
229
c1e065f3 230/* Return tree if target supports vector operations for COND_EXPR. */
d6b19f6b 231bool expand_vec_cond_expr_p (tree, tree);
6b7acc28 232
233/* Generate code for VEC_COND_EXPR. */
2c02962c 234extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
925c62d4 235/* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */
2c02962c 236extern rtx expand_vec_shift_expr (sepops, rtx);
925c62d4 237
f4803722 238/* Return tree if target supports vector operations for VEC_PERM_EXPR. */
e21c468f 239extern bool can_vec_perm_p (enum machine_mode, bool, const unsigned char *);
6cf89e04 240
f4803722 241/* Generate code for VEC_PERM_EXPR. */
e21c468f 242extern rtx expand_vec_perm (enum machine_mode, rtx, rtx, rtx, rtx);
6cf89e04 243
ebf4f764 244/* Return non-zero if target supports a given highpart multiplication. */
245extern int can_mult_highpart_p (enum machine_mode, bool);
246
247/* Generate code for MULT_HIGHPART_EXPR. */
248extern rtx expand_mult_highpart (enum machine_mode, rtx, rtx, rtx, bool);
249
d6bf3b14 250/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
251 if the target does not have such an insn. */
252
253static inline enum insn_code
254optab_handler (optab op, enum machine_mode mode)
255{
ee65118b 256 unsigned scode = (op << 16) | mode;
257 gcc_assert (op > LAST_CONV_OPTAB);
258 return raw_optab_handler (scode);
5a574e8b 259}
260
d6bf3b14 261/* Return the insn used to perform conversion OP from mode FROM_MODE
262 to mode TO_MODE; return CODE_FOR_nothing if the target does not have
263 such an insn. */
264
265static inline enum insn_code
266convert_optab_handler (convert_optab op, enum machine_mode to_mode,
267 enum machine_mode from_mode)
268{
ee65118b 269 unsigned scode = (op << 16) | (from_mode << 8) | to_mode;
270 gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB);
271 return raw_optab_handler (scode);
d6bf3b14 272}
273
ee65118b 274/* Like optab_handler, but for widening_operations that have a
275 TO_MODE and a FROM_MODE. */
d6bf3b14 276
ee65118b 277static inline enum insn_code
278widening_optab_handler (optab op, enum machine_mode to_mode,
279 enum machine_mode from_mode)
d6bf3b14 280{
ee65118b 281 unsigned scode = (op << 16) | to_mode;
282 if (to_mode != from_mode && from_mode != VOIDmode)
283 {
284 /* ??? Why does find_widening_optab_handler_and_mode attempt to
285 widen things that can't be widened? E.g. add_optab... */
286 if (op > LAST_CONV_OPTAB)
287 return CODE_FOR_nothing;
288 scode |= from_mode << 8;
289 }
290 return raw_optab_handler (scode);
d6bf3b14 291}
99bdde56 292
6b531606 293/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
294 if the target does not have such an insn. */
295
296static inline enum insn_code
297direct_optab_handler (direct_optab op, enum machine_mode mode)
298{
ee65118b 299 return optab_handler (op, mode);
6b531606 300}
301
4c79581c 302/* Return true if UNOPTAB is for a trapping-on-overflow operation. */
303
304static inline bool
305trapv_unoptab_p (optab unoptab)
306{
307 return (unoptab == negv_optab
308 || unoptab == absv_optab);
309}
310
311/* Return true if BINOPTAB is for a trapping-on-overflow operation. */
312
313static inline bool
314trapv_binoptab_p (optab binoptab)
315{
316 return (binoptab == addv_optab
317 || binoptab == subv_optab
318 || binoptab == smulv_optab);
319}
320
f36b9f69 321extern rtx optab_libfunc (optab optab, enum machine_mode mode);
322extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
323 enum machine_mode mode2);
39c56a89 324
26427966 325/* Describes an instruction that inserts or extracts a bitfield. */
326struct extraction_insn
327{
328 /* The code of the instruction. */
329 enum insn_code icode;
330
331 /* The mode that the structure operand should have. This is byte_mode
332 when using the legacy insv, extv and extzv patterns to access memory. */
333 enum machine_mode struct_mode;
334
335 /* The mode of the field to be inserted or extracted, and by extension
336 the mode of the insertion or extraction itself. */
337 enum machine_mode field_mode;
338
339 /* The mode of the field's bit position. This is only important
340 when the position is variable rather than constant. */
341 enum machine_mode pos_mode;
342};
343
344/* Enumerates the possible extraction_insn operations. */
345enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
346
347extern bool get_best_reg_extraction_insn (extraction_insn *,
348 enum extraction_pattern,
349 unsigned HOST_WIDE_INT,
350 enum machine_mode);
351
352extern bool get_best_mem_extraction_insn (extraction_insn *,
353 enum extraction_pattern,
354 HOST_WIDE_INT, HOST_WIDE_INT,
355 enum machine_mode);
356
39c56a89 357extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
358 rtx operand);
8786db1e 359
360/* Describes the type of an expand_operand. Each value is associated
361 with a create_*_operand function; see the comments above those
362 functions for details. */
363enum expand_operand_type {
364 EXPAND_FIXED,
365 EXPAND_OUTPUT,
366 EXPAND_INPUT,
367 EXPAND_CONVERT_TO,
368 EXPAND_CONVERT_FROM,
369 EXPAND_ADDRESS,
370 EXPAND_INTEGER
371};
372
373/* Information about an operand for instruction expansion. */
374struct expand_operand {
375 /* The type of operand. */
376 ENUM_BITFIELD (expand_operand_type) type : 8;
377
378 /* True if any conversion should treat VALUE as being unsigned
379 rather than signed. Only meaningful for certain types. */
380 unsigned int unsigned_p : 1;
381
382 /* Unused; available for future use. */
383 unsigned int unused : 7;
384
385 /* The mode passed to the convert_*_operand function. It has a
386 type-dependent meaning. */
387 ENUM_BITFIELD (machine_mode) mode : 16;
388
389 /* The value of the operand. */
390 rtx value;
391};
392
393/* Initialize OP with the given fields. Initialise the other fields
394 to their default values. */
395
396static inline void
397create_expand_operand (struct expand_operand *op,
398 enum expand_operand_type type,
399 rtx value, enum machine_mode mode,
400 bool unsigned_p)
401{
402 op->type = type;
403 op->unsigned_p = unsigned_p;
404 op->unused = 0;
405 op->mode = mode;
406 op->value = value;
407}
408
409/* Make OP describe an operand that must use rtx X, even if X is volatile. */
410
411static inline void
412create_fixed_operand (struct expand_operand *op, rtx x)
413{
414 create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
415}
416
417/* Make OP describe an output operand that must have mode MODE.
418 X, if nonnull, is a suggestion for where the output should be stored.
419 It is OK for VALUE to be inconsistent with MODE, although it will just
420 be ignored in that case. */
421
422static inline void
423create_output_operand (struct expand_operand *op, rtx x,
424 enum machine_mode mode)
425{
426 create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
427}
428
429/* Make OP describe an input operand that must have mode MODE and
430 value VALUE; MODE cannot be VOIDmode. The backend may request that
431 VALUE be copied into a different kind of rtx before being passed
432 as an operand. */
433
434static inline void
435create_input_operand (struct expand_operand *op, rtx value,
436 enum machine_mode mode)
437{
438 create_expand_operand (op, EXPAND_INPUT, value, mode, false);
439}
440
441/* Like create_input_operand, except that VALUE must first be converted
442 to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */
443
444static inline void
445create_convert_operand_to (struct expand_operand *op, rtx value,
446 enum machine_mode mode, bool unsigned_p)
447{
448 create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
449}
450
451/* Make OP describe an input operand that should have the same value
452 as VALUE, after any mode conversion that the backend might request.
453 If VALUE is a CONST_INT, it should be treated as having mode MODE.
454 UNSIGNED_P says whether VALUE is unsigned. */
455
456static inline void
457create_convert_operand_from (struct expand_operand *op, rtx value,
458 enum machine_mode mode, bool unsigned_p)
459{
460 create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
461}
462
463extern void create_convert_operand_from_type (struct expand_operand *op,
464 rtx value, tree type);
465
466/* Make OP describe an input Pmode address operand. VALUE is the value
467 of the address, but it may need to be converted to Pmode first. */
468
469static inline void
470create_address_operand (struct expand_operand *op, rtx value)
471{
472 create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
473}
474
475/* Make OP describe an input operand that has value INTVAL and that has
476 no inherent mode. This function should only be used for operands that
477 are always expand-time constants. The backend may request that INTVAL
478 be copied into a different kind of rtx, but it must specify the mode
479 of that rtx if so. */
480
481static inline void
482create_integer_operand (struct expand_operand *op, HOST_WIDE_INT intval)
483{
484 create_expand_operand (op, EXPAND_INTEGER, GEN_INT (intval), VOIDmode, false);
485}
486
e09c2930 487extern bool valid_multiword_target_p (rtx);
488
8786db1e 489extern bool maybe_legitimize_operands (enum insn_code icode,
490 unsigned int opno, unsigned int nops,
491 struct expand_operand *ops);
492extern rtx maybe_gen_insn (enum insn_code icode, unsigned int nops,
493 struct expand_operand *ops);
494extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
495 struct expand_operand *ops);
496extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
497 struct expand_operand *ops);
498extern void expand_insn (enum insn_code icode, unsigned int nops,
499 struct expand_operand *ops);
500extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
501 struct expand_operand *ops);
502
39c56a89 503extern rtx prepare_operand (enum insn_code, rtx, int, enum machine_mode,
504 enum machine_mode, int);
505
ee65118b 506extern void gen_int_libfunc (optab, const char *, char, enum machine_mode);
507extern void gen_fp_libfunc (optab, const char *, char, enum machine_mode);
508extern void gen_fixed_libfunc (optab, const char *, char, enum machine_mode);
509extern void gen_signed_fixed_libfunc (optab, const char *, char,
510 enum machine_mode);
511extern void gen_unsigned_fixed_libfunc (optab, const char *, char,
512 enum machine_mode);
513extern void gen_int_fp_libfunc (optab, const char *, char, enum machine_mode);
514extern void gen_intv_fp_libfunc (optab, const char *, char, enum machine_mode);
515extern void gen_int_fp_fixed_libfunc (optab, const char *, char,
516 enum machine_mode);
517extern void gen_int_fp_signed_fixed_libfunc (optab, const char *, char,
518 enum machine_mode);
519extern void gen_int_fixed_libfunc (optab, const char *, char,
520 enum machine_mode);
521extern void gen_int_signed_fixed_libfunc (optab, const char *, char,
522 enum machine_mode);
523extern void gen_int_unsigned_fixed_libfunc (optab, const char *, char,
524 enum machine_mode);
525
526extern void gen_interclass_conv_libfunc (convert_optab, const char *,
527 enum machine_mode, enum machine_mode);
528extern void gen_int_to_fp_conv_libfunc (convert_optab, const char *,
529 enum machine_mode, enum machine_mode);
530extern void gen_ufloat_conv_libfunc (convert_optab, const char *,
531 enum machine_mode, enum machine_mode);
532extern void gen_int_to_fp_nondecimal_conv_libfunc (convert_optab,
533 const char *,
534 enum machine_mode,
535 enum machine_mode);
536extern void gen_fp_to_int_conv_libfunc (convert_optab, const char *,
537 enum machine_mode, enum machine_mode);
538extern void gen_intraclass_conv_libfunc (convert_optab, const char *,
539 enum machine_mode, enum machine_mode);
540extern void gen_trunc_conv_libfunc (convert_optab, const char *,
541 enum machine_mode, enum machine_mode);
542extern void gen_extend_conv_libfunc (convert_optab, const char *,
543 enum machine_mode, enum machine_mode);
544extern void gen_fract_conv_libfunc (convert_optab, const char *,
545 enum machine_mode, enum machine_mode);
546extern void gen_fractuns_conv_libfunc (convert_optab, const char *,
547 enum machine_mode, enum machine_mode);
548extern void gen_satfract_conv_libfunc (convert_optab, const char *,
549 enum machine_mode, enum machine_mode);
550extern void gen_satfractuns_conv_libfunc (convert_optab, const char *,
551 enum machine_mode,
552 enum machine_mode);
553
d8fc4d0b 554#endif /* GCC_OPTABS_H */