]>
Commit | Line | Data |
---|---|---|
e78d8e51 ZW |
1 | /* Definitions for code generation pass of GNU compiler. |
2 | Copyright (C) 2001 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GNU CC. | |
5 | ||
6 | GNU CC 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 2, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GNU CC 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 GNU CC; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
19 | Boston, MA 02111-1307, USA. */ | |
20 | ||
21 | #ifndef GCC_OPTABS_H | |
22 | #define GCC_OPTABS_H | |
23 | ||
24 | #include "insn-codes.h" | |
25 | ||
26 | /* Optabs are tables saying how to generate insn bodies | |
27 | for various machine modes and numbers of operands. | |
28 | Each optab applies to one operation. | |
29 | For example, add_optab applies to addition. | |
30 | ||
31 | The insn_code slot is the enum insn_code that says how to | |
32 | generate an insn for this operation on a particular machine mode. | |
33 | It is CODE_FOR_nothing if there is no such insn on the target machine. | |
34 | ||
35 | The `lib_call' slot is the name of the library function that | |
36 | can be used to perform the operation. | |
37 | ||
38 | A few optabs, such as move_optab and cmp_optab, are used | |
39 | by special code. */ | |
40 | ||
41 | typedef struct optab | |
42 | { | |
43 | enum rtx_code code; | |
44 | struct { | |
45 | enum insn_code insn_code; | |
46 | rtx libfunc; | |
47 | } handlers [NUM_MACHINE_MODES]; | |
48 | } * optab; | |
49 | ||
50 | /* Given an enum insn_code, access the function to construct | |
51 | the body of that kind of insn. */ | |
52 | #define GEN_FCN(CODE) (*insn_data[(int) (CODE)].genfun) | |
53 | ||
54 | /* Enumeration of valid indexes into optab_table. */ | |
55 | enum optab_index | |
56 | { | |
57 | OTI_add, | |
58 | OTI_addv, | |
59 | OTI_sub, | |
60 | OTI_subv, | |
61 | ||
62 | /* Signed and fp multiply */ | |
63 | OTI_smul, | |
64 | OTI_smulv, | |
65 | /* Signed multiply, return high word */ | |
66 | OTI_smul_highpart, | |
67 | OTI_umul_highpart, | |
68 | /* Signed multiply with result one machine mode wider than args */ | |
69 | OTI_smul_widen, | |
70 | OTI_umul_widen, | |
71 | ||
72 | /* Signed divide */ | |
73 | OTI_sdiv, | |
74 | OTI_sdivv, | |
75 | /* Signed divide-and-remainder in one */ | |
76 | OTI_sdivmod, | |
77 | OTI_udiv, | |
78 | OTI_udivmod, | |
79 | /* Signed remainder */ | |
80 | OTI_smod, | |
81 | OTI_umod, | |
e78d8e51 ZW |
82 | /* Convert float to integer in float fmt */ |
83 | OTI_ftrunc, | |
84 | ||
85 | /* Logical and */ | |
86 | OTI_and, | |
87 | /* Logical or */ | |
88 | OTI_ior, | |
89 | /* Logical xor */ | |
90 | OTI_xor, | |
91 | ||
92 | /* Arithmetic shift left */ | |
93 | OTI_ashl, | |
94 | /* Logical shift right */ | |
95 | OTI_lshr, | |
96 | /* Arithmetic shift right */ | |
97 | OTI_ashr, | |
98 | /* Rotate left */ | |
99 | OTI_rotl, | |
100 | /* Rotate right */ | |
101 | OTI_rotr, | |
102 | /* Signed and floating-point minimum value */ | |
103 | OTI_smin, | |
104 | /* Signed and floating-point maximum value */ | |
105 | OTI_smax, | |
106 | /* Unsigned minimum value */ | |
107 | OTI_umin, | |
108 | /* Unsigned maximum value */ | |
109 | OTI_umax, | |
110 | ||
111 | /* Move instruction. */ | |
112 | OTI_mov, | |
113 | /* Move, preserving high part of register. */ | |
114 | OTI_movstrict, | |
115 | ||
116 | /* Unary operations */ | |
117 | /* Negation */ | |
118 | OTI_neg, | |
119 | OTI_negv, | |
120 | /* Abs value */ | |
121 | OTI_abs, | |
122 | OTI_absv, | |
123 | /* Bitwise not */ | |
124 | OTI_one_cmpl, | |
125 | /* Find first bit set */ | |
126 | OTI_ffs, | |
127 | /* Square root */ | |
128 | OTI_sqrt, | |
129 | /* Sine */ | |
130 | OTI_sin, | |
131 | /* Cosine */ | |
132 | OTI_cos, | |
133 | ||
134 | /* Compare insn; two operands. */ | |
135 | OTI_cmp, | |
136 | /* Used only for libcalls for unsigned comparisons. */ | |
137 | OTI_ucmp, | |
138 | /* tst insn; compare one operand against 0 */ | |
139 | OTI_tst, | |
140 | ||
141 | /* String length */ | |
142 | OTI_strlen, | |
143 | ||
144 | /* Combined compare & jump/store flags/move operations. */ | |
145 | OTI_cbranch, | |
146 | OTI_cmov, | |
147 | OTI_cstore, | |
148 | ||
149 | /* Push instruction. */ | |
150 | OTI_push, | |
151 | ||
152 | OTI_MAX | |
153 | }; | |
154 | ||
155 | extern optab optab_table[OTI_MAX]; | |
156 | ||
157 | #define add_optab (optab_table[OTI_add]) | |
158 | #define sub_optab (optab_table[OTI_sub]) | |
159 | #define smul_optab (optab_table[OTI_smul]) | |
160 | #define addv_optab (optab_table[OTI_addv]) | |
161 | #define subv_optab (optab_table[OTI_subv]) | |
162 | #define smul_highpart_optab (optab_table[OTI_smul_highpart]) | |
163 | #define umul_highpart_optab (optab_table[OTI_umul_highpart]) | |
164 | #define smul_widen_optab (optab_table[OTI_smul_widen]) | |
165 | #define umul_widen_optab (optab_table[OTI_umul_widen]) | |
166 | #define sdiv_optab (optab_table[OTI_sdiv]) | |
167 | #define smulv_optab (optab_table[OTI_smulv]) | |
168 | #define sdivv_optab (optab_table[OTI_sdivv]) | |
169 | #define sdivmod_optab (optab_table[OTI_sdivmod]) | |
170 | #define udiv_optab (optab_table[OTI_udiv]) | |
171 | #define udivmod_optab (optab_table[OTI_udivmod]) | |
172 | #define smod_optab (optab_table[OTI_smod]) | |
173 | #define umod_optab (optab_table[OTI_umod]) | |
e78d8e51 ZW |
174 | #define ftrunc_optab (optab_table[OTI_ftrunc]) |
175 | #define and_optab (optab_table[OTI_and]) | |
176 | #define ior_optab (optab_table[OTI_ior]) | |
177 | #define xor_optab (optab_table[OTI_xor]) | |
178 | #define ashl_optab (optab_table[OTI_ashl]) | |
179 | #define lshr_optab (optab_table[OTI_lshr]) | |
180 | #define ashr_optab (optab_table[OTI_ashr]) | |
181 | #define rotl_optab (optab_table[OTI_rotl]) | |
182 | #define rotr_optab (optab_table[OTI_rotr]) | |
183 | #define smin_optab (optab_table[OTI_smin]) | |
184 | #define smax_optab (optab_table[OTI_smax]) | |
185 | #define umin_optab (optab_table[OTI_umin]) | |
186 | #define umax_optab (optab_table[OTI_umax]) | |
187 | ||
188 | #define mov_optab (optab_table[OTI_mov]) | |
189 | #define movstrict_optab (optab_table[OTI_movstrict]) | |
190 | ||
191 | #define neg_optab (optab_table[OTI_neg]) | |
192 | #define negv_optab (optab_table[OTI_negv]) | |
193 | #define abs_optab (optab_table[OTI_abs]) | |
194 | #define absv_optab (optab_table[OTI_absv]) | |
195 | #define one_cmpl_optab (optab_table[OTI_one_cmpl]) | |
196 | #define ffs_optab (optab_table[OTI_ffs]) | |
197 | #define sqrt_optab (optab_table[OTI_sqrt]) | |
198 | #define sin_optab (optab_table[OTI_sin]) | |
199 | #define cos_optab (optab_table[OTI_cos]) | |
200 | ||
201 | #define cmp_optab (optab_table[OTI_cmp]) | |
202 | #define ucmp_optab (optab_table[OTI_ucmp]) | |
203 | #define tst_optab (optab_table[OTI_tst]) | |
204 | ||
205 | #define strlen_optab (optab_table[OTI_strlen]) | |
206 | ||
207 | #define cbranch_optab (optab_table[OTI_cbranch]) | |
208 | #define cmov_optab (optab_table[OTI_cmov]) | |
209 | #define cstore_optab (optab_table[OTI_cstore]) | |
210 | #define push_optab (optab_table[OTI_push]) | |
211 | ||
212 | /* Tables of patterns for extending one integer mode to another. */ | |
213 | extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2]; | |
214 | ||
215 | /* Tables of patterns for converting between fixed and floating point. */ | |
216 | extern enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; | |
217 | extern enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; | |
218 | extern enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; | |
219 | ||
220 | /* These arrays record the insn_code of insns that may be needed to | |
221 | perform input and output reloads of special objects. They provide a | |
222 | place to pass a scratch register. */ | |
223 | extern enum insn_code reload_in_optab[NUM_MACHINE_MODES]; | |
224 | extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; | |
225 | ||
226 | /* Contains the optab used for each rtx code. */ | |
227 | extern optab code_to_optab[NUM_RTX_CODE + 1]; | |
228 | ||
e78d8e51 ZW |
229 | \f |
230 | typedef rtx (*rtxfun) PARAMS ((rtx)); | |
231 | ||
232 | /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) | |
233 | gives the gen_function to make a branch to test that condition. */ | |
234 | ||
235 | extern rtxfun bcc_gen_fctn[NUM_RTX_CODE]; | |
236 | ||
237 | /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) | |
238 | gives the insn code to make a store-condition insn | |
239 | to test that condition. */ | |
240 | ||
241 | extern enum insn_code setcc_gen_code[NUM_RTX_CODE]; | |
242 | ||
243 | #ifdef HAVE_conditional_move | |
244 | /* Indexed by the machine mode, gives the insn code to make a conditional | |
245 | move insn. */ | |
246 | ||
247 | extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; | |
248 | #endif | |
249 | ||
250 | /* This array records the insn_code of insns to perform block moves. */ | |
251 | extern enum insn_code movstr_optab[NUM_MACHINE_MODES]; | |
252 | ||
253 | /* This array records the insn_code of insns to perform block clears. */ | |
254 | extern enum insn_code clrstr_optab[NUM_MACHINE_MODES]; | |
255 | ||
256 | /* Define functions given in optabs.c. */ | |
257 | ||
258 | /* Expand a binary operation given optab and rtx operands. */ | |
259 | extern rtx expand_binop PARAMS ((enum machine_mode, optab, rtx, rtx, rtx, | |
260 | int, enum optab_methods)); | |
261 | ||
262 | /* Expand a binary operation with both signed and unsigned forms. */ | |
263 | extern rtx sign_expand_binop PARAMS ((enum machine_mode, optab, optab, rtx, | |
264 | rtx, rtx, int, enum optab_methods)); | |
265 | ||
266 | /* Generate code to perform an operation on two operands with two results. */ | |
267 | extern int expand_twoval_binop PARAMS ((optab, rtx, rtx, rtx, rtx, int)); | |
268 | ||
269 | /* Expand a unary arithmetic operation given optab rtx operand. */ | |
270 | extern rtx expand_unop PARAMS ((enum machine_mode, optab, rtx, rtx, int)); | |
271 | ||
272 | /* Expand the absolute value operation. */ | |
273 | extern rtx expand_abs PARAMS ((enum machine_mode, rtx, rtx, int, int)); | |
274 | ||
275 | /* Expand the complex absolute value operation. */ | |
276 | extern rtx expand_complex_abs PARAMS ((enum machine_mode, rtx, rtx, int)); | |
277 | ||
278 | /* Generate an instruction with a given INSN_CODE with an output and | |
279 | an input. */ | |
280 | extern void emit_unop_insn PARAMS ((int, rtx, rtx, enum rtx_code)); | |
281 | ||
282 | /* Emit code to perform a series of operations on a multi-word quantity, one | |
283 | word at a time. */ | |
284 | extern rtx emit_no_conflict_block PARAMS ((rtx, rtx, rtx, rtx, rtx)); | |
285 | ||
286 | /* Emit one rtl instruction to store zero in specified rtx. */ | |
287 | extern void emit_clr_insn PARAMS ((rtx)); | |
288 | ||
289 | /* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */ | |
290 | extern void emit_0_to_1_insn PARAMS ((rtx)); | |
291 | ||
292 | /* Emit one rtl insn to compare two rtx's. */ | |
293 | extern void emit_cmp_insn PARAMS ((rtx, rtx, enum rtx_code, rtx, | |
294 | enum machine_mode, int, unsigned int)); | |
295 | ||
296 | /* The various uses that a comparison can have; used by can_compare_p: | |
297 | jumps, conditional moves, store flag operations. */ | |
298 | enum can_compare_purpose | |
299 | { | |
300 | ccp_jump, | |
301 | ccp_cmov, | |
302 | ccp_store_flag | |
303 | }; | |
304 | ||
305 | /* Nonzero if a compare of mode MODE can be done straightforwardly | |
306 | (without splitting it into pieces). */ | |
307 | extern int can_compare_p PARAMS ((enum rtx_code, enum machine_mode, | |
308 | enum can_compare_purpose)); | |
309 | ||
310 | extern void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx, | |
311 | enum machine_mode *, int *, int, | |
312 | enum can_compare_purpose)); | |
313 | ||
314 | extern rtx prepare_operand PARAMS ((int, rtx, int, enum machine_mode, | |
315 | enum machine_mode, int)); | |
316 | ||
317 | /* Return the INSN_CODE to use for an extend operation. */ | |
318 | extern enum insn_code can_extend_p PARAMS ((enum machine_mode, | |
319 | enum machine_mode, int)); | |
320 | ||
321 | /* Generate the body of an insn to extend Y (with mode MFROM) | |
322 | into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ | |
323 | extern rtx gen_extend_insn PARAMS ((rtx, rtx, enum machine_mode, | |
324 | enum machine_mode, int)); | |
325 | ||
326 | /* Initialize the tables that control conversion between fixed and | |
327 | floating values. */ | |
328 | extern void init_fixtab PARAMS ((void)); | |
329 | extern void init_floattab PARAMS ((void)); | |
330 | ||
331 | /* Generate code for a FLOAT_EXPR. */ | |
332 | extern void expand_float PARAMS ((rtx, rtx, int)); | |
333 | ||
334 | /* Generate code for a FIX_EXPR. */ | |
335 | extern void expand_fix PARAMS ((rtx, rtx, int)); | |
336 | ||
337 | #endif /* GCC_OPTABS_H */ |