]>
Commit | Line | Data |
---|---|---|
385399a8 | 1 | /* IR-agnostic target query functions relating to optabs |
818ab71a | 2 | Copyright (C) 2001-2016 Free Software Foundation, Inc. |
385399a8 RS |
3 | |
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING3. If not see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #ifndef GCC_OPTABS_QUERY_H | |
21 | #define GCC_OPTABS_QUERY_H | |
22 | ||
23 | #include "insn-opinit.h" | |
24 | ||
25 | /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing | |
26 | if the target does not have such an insn. */ | |
27 | ||
28 | inline enum insn_code | |
29 | optab_handler (optab op, machine_mode mode) | |
30 | { | |
31 | unsigned scode = (op << 16) | mode; | |
32 | gcc_assert (op > LAST_CONV_OPTAB); | |
33 | return raw_optab_handler (scode); | |
34 | } | |
35 | ||
36 | /* Return the insn used to perform conversion OP from mode FROM_MODE | |
37 | to mode TO_MODE; return CODE_FOR_nothing if the target does not have | |
38 | such an insn. */ | |
39 | ||
40 | inline enum insn_code | |
41 | convert_optab_handler (convert_optab op, machine_mode to_mode, | |
42 | machine_mode from_mode) | |
43 | { | |
44 | unsigned scode = (op << 16) | (from_mode << 8) | to_mode; | |
45 | gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB); | |
46 | return raw_optab_handler (scode); | |
47 | } | |
48 | ||
d95ab70a RS |
49 | enum insn_code convert_optab_handler (convert_optab, machine_mode, |
50 | machine_mode, optimization_type); | |
51 | ||
385399a8 RS |
52 | /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing |
53 | if the target does not have such an insn. */ | |
54 | ||
55 | inline enum insn_code | |
56 | direct_optab_handler (direct_optab op, machine_mode mode) | |
57 | { | |
58 | return optab_handler (op, mode); | |
59 | } | |
60 | ||
d95ab70a RS |
61 | enum insn_code direct_optab_handler (convert_optab, machine_mode, |
62 | optimization_type); | |
63 | ||
385399a8 RS |
64 | /* Return true if UNOPTAB is for a trapping-on-overflow operation. */ |
65 | ||
66 | inline bool | |
67 | trapv_unoptab_p (optab unoptab) | |
68 | { | |
69 | return (unoptab == negv_optab | |
70 | || unoptab == absv_optab); | |
71 | } | |
72 | ||
73 | /* Return true if BINOPTAB is for a trapping-on-overflow operation. */ | |
74 | ||
75 | inline bool | |
76 | trapv_binoptab_p (optab binoptab) | |
77 | { | |
78 | return (binoptab == addv_optab | |
79 | || binoptab == subv_optab | |
80 | || binoptab == smulv_optab); | |
81 | } | |
82 | ||
42fd8198 IE |
83 | /* Return insn code for a comparison operator with VMODE |
84 | resultin MASK_MODE, unsigned if UNS is true. */ | |
85 | ||
86 | static inline enum insn_code | |
87 | get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns) | |
88 | { | |
89 | optab tab = uns ? vec_cmpu_optab : vec_cmp_optab; | |
90 | return convert_optab_handler (tab, vmode, mask_mode); | |
91 | } | |
92 | ||
385399a8 RS |
93 | /* Return insn code for a conditional operator with a comparison in |
94 | mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */ | |
95 | ||
96 | inline enum insn_code | |
97 | get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns) | |
98 | { | |
99 | enum insn_code icode = CODE_FOR_nothing; | |
100 | if (uns) | |
101 | icode = convert_optab_handler (vcondu_optab, vmode, cmode); | |
102 | else | |
103 | icode = convert_optab_handler (vcond_optab, vmode, cmode); | |
104 | return icode; | |
105 | } | |
106 | ||
a414c77f IE |
107 | /* Return insn code for a conditional operator with a mask mode |
108 | MMODE resulting in a value of mode VMODE. */ | |
109 | ||
110 | static inline enum insn_code | |
111 | get_vcond_mask_icode (machine_mode vmode, machine_mode mmode) | |
112 | { | |
113 | return convert_optab_handler (vcond_mask_optab, vmode, mmode); | |
114 | } | |
115 | ||
385399a8 RS |
116 | /* Enumerates the possible extraction_insn operations. */ |
117 | enum extraction_pattern { EP_insv, EP_extv, EP_extzv }; | |
118 | ||
119 | /* Describes an instruction that inserts or extracts a bitfield. */ | |
120 | struct extraction_insn | |
121 | { | |
122 | /* The code of the instruction. */ | |
123 | enum insn_code icode; | |
124 | ||
125 | /* The mode that the structure operand should have. This is byte_mode | |
126 | when using the legacy insv, extv and extzv patterns to access memory. */ | |
127 | machine_mode struct_mode; | |
128 | ||
129 | /* The mode of the field to be inserted or extracted, and by extension | |
130 | the mode of the insertion or extraction itself. */ | |
131 | machine_mode field_mode; | |
132 | ||
133 | /* The mode of the field's bit position. This is only important | |
134 | when the position is variable rather than constant. */ | |
135 | machine_mode pos_mode; | |
136 | }; | |
137 | ||
138 | bool get_best_reg_extraction_insn (extraction_insn *, | |
139 | enum extraction_pattern, | |
140 | unsigned HOST_WIDE_INT, machine_mode); | |
141 | bool get_best_mem_extraction_insn (extraction_insn *, | |
142 | enum extraction_pattern, | |
143 | HOST_WIDE_INT, HOST_WIDE_INT, machine_mode); | |
144 | ||
145 | enum insn_code can_extend_p (machine_mode, machine_mode, int); | |
146 | enum insn_code can_float_p (machine_mode, machine_mode, int); | |
147 | enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *); | |
148 | bool can_conditionally_move_p (machine_mode mode); | |
149 | bool can_vec_perm_p (machine_mode, bool, const unsigned char *); | |
150 | enum insn_code widening_optab_handler (optab, machine_mode, machine_mode); | |
151 | /* Find a widening optab even if it doesn't widen as much as we want. */ | |
152 | #define find_widening_optab_handler(A,B,C,D) \ | |
153 | find_widening_optab_handler_and_mode (A, B, C, D, NULL) | |
154 | enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode, | |
155 | machine_mode, int, | |
156 | machine_mode *); | |
157 | int can_mult_highpart_p (machine_mode, bool); | |
045c1278 | 158 | bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool); |
385399a8 RS |
159 | bool can_compare_and_swap_p (machine_mode, bool); |
160 | bool can_atomic_exchange_p (machine_mode, bool); | |
161 | bool lshift_cheap_p (bool); | |
162 | ||
163 | #endif |