1 /* Definitions for code generation pass of GNU compiler. 2 Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 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 2, 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 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 struct optab_handlers GTY(()) 42 { 43 enum insn_code insn_code; 44 rtx libfunc; 45 }; 46 47 struct optab GTY(()) 48 { 49 enum rtx_code code; 50 struct optab_handlers handlers[NUM_MACHINE_MODES]; 51 }; 52 typedef struct optab * optab; 53 54 /* A convert_optab is for some sort of conversion operation between 55 modes. The first array index is the destination mode, the second 56 is the source mode. */ 57 struct convert_optab GTY(()) 58 { 59 enum rtx_code code; 60 struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES]; 61 }; 62 typedef struct convert_optab *convert_optab; 63 64 /* Given an enum insn_code, access the function to construct 65 the body of that kind of insn. */ 66 #define GEN_FCN(CODE) (insn_data[CODE].genfun) 67 68 /* Enumeration of valid indexes into optab_table. */ 69 enum optab_index 70 { 71 OTI_add, 72 OTI_addv, 73 OTI_sub, 74 OTI_subv, 75 76 /* Signed and fp multiply */ 77 OTI_smul, 78 OTI_smulv, 79 /* Signed multiply, return high word */ 80 OTI_smul_highpart, 81 OTI_umul_highpart, 82 /* Signed multiply with result one machine mode wider than args */ 83 OTI_smul_widen, 84 OTI_umul_widen, 85 86 /* Signed divide */ 87 OTI_sdiv, 88 OTI_sdivv, 89 /* Signed divide-and-remainder in one */ 90 OTI_sdivmod, 91 OTI_udiv, 92 OTI_udivmod, 93 /* Signed remainder */ 94 OTI_smod, 95 OTI_umod, 96 /* Convert float to integer in float fmt */ 97 OTI_ftrunc, 98 99 /* Logical and */ 100 OTI_and, 101 /* Logical or */ 102 OTI_ior, 103 /* Logical xor */ 104 OTI_xor, 105 106 /* Arithmetic shift left */ 107 OTI_ashl, 108 /* Logical shift right */ 109 OTI_lshr, 110 /* Arithmetic shift right */ 111 OTI_ashr, 112 /* Rotate left */ 113 OTI_rotl, 114 /* Rotate right */ 115 OTI_rotr, 116 /* Signed and floating-point minimum value */ 117 OTI_smin, 118 /* Signed and floating-point maximum value */ 119 OTI_smax, 120 /* Unsigned minimum value */ 121 OTI_umin, 122 /* Unsigned maximum value */ 123 OTI_umax, 124 /* Power */ 125 OTI_pow, 126 /* Arc tangent of y/x */ 127 OTI_atan2, 128 129 /* Move instruction. */ 130 OTI_mov, 131 /* Move, preserving high part of register. */ 132 OTI_movstrict, 133 134 /* Unary operations */ 135 /* Negation */ 136 OTI_neg, 137 OTI_negv, 138 /* Abs value */ 139 OTI_abs, 140 OTI_absv, 141 /* Bitwise not */ 142 OTI_one_cmpl, 143 /* Bit scanning and counting */ 144 OTI_ffs, 145 OTI_clz, 146 OTI_ctz, 147 OTI_popcount, 148 OTI_parity, 149 /* Square root */ 150 OTI_sqrt, 151 /* Sine */ 152 OTI_sin, 153 /* Cosine */ 154 OTI_cos, 155 /* Exponential */ 156 OTI_exp, 157 /* Natural Logarithm */ 158 OTI_log, 159 /* Rounding functions */ 160 OTI_floor, 161 OTI_ceil, 162 OTI_trunc, 163 OTI_round, 164 OTI_nearbyint, 165 /* Tangent */ 166 OTI_tan, 167 /* Inverse tangent */ 168 OTI_atan, 169 170 /* Compare insn; two operands. */ 171 OTI_cmp, 172 /* Used only for libcalls for unsigned comparisons. */ 173 OTI_ucmp, 174 /* tst insn; compare one operand against 0 */ 175 OTI_tst, 176 177 /* Floating point comparison optabs - used primarily for libfuncs */ 178 OTI_eq, 179 OTI_ne, 180 OTI_gt, 181 OTI_ge, 182 OTI_lt, 183 OTI_le, 184 OTI_unord, 185 186 /* String length */ 187 OTI_strlen, 188 189 /* Combined compare & jump/store flags/move operations. */ 190 OTI_cbranch, 191 OTI_cmov, 192 OTI_cstore, 193 194 /* Push instruction. */ 195 OTI_push, 196 197 /* Conditional add instruction. */ 198 OTI_addcc, 199 200 /* Set specified field of vector operand. */ 201 OTI_vec_set, 202 /* Extract specified field of vector operand. */ 203 OTI_vec_extract, 204 /* Initialize vector operand. */ 205 OTI_vec_init, 206 207 OTI_MAX 208 }; 209 210 extern GTY(()) optab optab_table[OTI_MAX]; 211 212 #define add_optab (optab_table[OTI_add]) 213 #define sub_optab (optab_table[OTI_sub]) 214 #define smul_optab (optab_table[OTI_smul]) 215 #define addv_optab (optab_table[OTI_addv]) 216 #define subv_optab (optab_table[OTI_subv]) 217 #define smul_highpart_optab (optab_table[OTI_smul_highpart]) 218 #define umul_highpart_optab (optab_table[OTI_umul_highpart]) 219 #define smul_widen_optab (optab_table[OTI_smul_widen]) 220 #define umul_widen_optab (optab_table[OTI_umul_widen]) 221 #define sdiv_optab (optab_table[OTI_sdiv]) 222 #define smulv_optab (optab_table[OTI_smulv]) 223 #define sdivv_optab (optab_table[OTI_sdivv]) 224 #define sdivmod_optab (optab_table[OTI_sdivmod]) 225 #define udiv_optab (optab_table[OTI_udiv]) 226 #define udivmod_optab (optab_table[OTI_udivmod]) 227 #define smod_optab (optab_table[OTI_smod]) 228 #define umod_optab (optab_table[OTI_umod]) 229 #define ftrunc_optab (optab_table[OTI_ftrunc]) 230 #define and_optab (optab_table[OTI_and]) 231 #define ior_optab (optab_table[OTI_ior]) 232 #define xor_optab (optab_table[OTI_xor]) 233 #define ashl_optab (optab_table[OTI_ashl]) 234 #define lshr_optab (optab_table[OTI_lshr]) 235 #define ashr_optab (optab_table[OTI_ashr]) 236 #define rotl_optab (optab_table[OTI_rotl]) 237 #define rotr_optab (optab_table[OTI_rotr]) 238 #define smin_optab (optab_table[OTI_smin]) 239 #define smax_optab (optab_table[OTI_smax]) 240 #define umin_optab (optab_table[OTI_umin]) 241 #define umax_optab (optab_table[OTI_umax]) 242 #define pow_optab (optab_table[OTI_pow]) 243 #define atan2_optab (optab_table[OTI_atan2]) 244 245 #define mov_optab (optab_table[OTI_mov]) 246 #define movstrict_optab (optab_table[OTI_movstrict]) 247 248 #define neg_optab (optab_table[OTI_neg]) 249 #define negv_optab (optab_table[OTI_negv]) 250 #define abs_optab (optab_table[OTI_abs]) 251 #define absv_optab (optab_table[OTI_absv]) 252 #define one_cmpl_optab (optab_table[OTI_one_cmpl]) 253 #define ffs_optab (optab_table[OTI_ffs]) 254 #define clz_optab (optab_table[OTI_clz]) 255 #define ctz_optab (optab_table[OTI_ctz]) 256 #define popcount_optab (optab_table[OTI_popcount]) 257 #define parity_optab (optab_table[OTI_parity]) 258 #define sqrt_optab (optab_table[OTI_sqrt]) 259 #define sin_optab (optab_table[OTI_sin]) 260 #define cos_optab (optab_table[OTI_cos]) 261 #define exp_optab (optab_table[OTI_exp]) 262 #define log_optab (optab_table[OTI_log]) 263 #define floor_optab (optab_table[OTI_floor]) 264 #define ceil_optab (optab_table[OTI_ceil]) 265 #define btrunc_optab (optab_table[OTI_trunc]) 266 #define round_optab (optab_table[OTI_round]) 267 #define nearbyint_optab (optab_table[OTI_nearbyint]) 268 #define tan_optab (optab_table[OTI_tan]) 269 #define atan_optab (optab_table[OTI_atan]) 270 271 #define cmp_optab (optab_table[OTI_cmp]) 272 #define ucmp_optab (optab_table[OTI_ucmp]) 273 #define tst_optab (optab_table[OTI_tst]) 274 275 #define eq_optab (optab_table[OTI_eq]) 276 #define ne_optab (optab_table[OTI_ne]) 277 #define gt_optab (optab_table[OTI_gt]) 278 #define ge_optab (optab_table[OTI_ge]) 279 #define lt_optab (optab_table[OTI_lt]) 280 #define le_optab (optab_table[OTI_le]) 281 #define unord_optab (optab_table[OTI_unord]) 282 283 #define strlen_optab (optab_table[OTI_strlen]) 284 285 #define cbranch_optab (optab_table[OTI_cbranch]) 286 #define cmov_optab (optab_table[OTI_cmov]) 287 #define cstore_optab (optab_table[OTI_cstore]) 288 #define push_optab (optab_table[OTI_push]) 289 #define addcc_optab (optab_table[OTI_addcc]) 290 291 #define vec_set_optab (optab_table[OTI_vec_set]) 292 #define vec_extract_optab (optab_table[OTI_vec_extract]) 293 #define vec_init_optab (optab_table[OTI_vec_init]) 294 295 /* Conversion optabs have their own table and indexes. */ 296 enum convert_optab_index 297 { 298 CTI_sext, 299 CTI_zext, 300 CTI_trunc, 301 302 CTI_sfix, 303 CTI_ufix, 304 305 CTI_sfixtrunc, 306 CTI_ufixtrunc, 307 308 CTI_sfloat, 309 CTI_ufloat, 310 311 CTI_MAX 312 }; 313 314 extern GTY(()) convert_optab convert_optab_table[CTI_MAX]; 315 316 #define sext_optab (convert_optab_table[CTI_sext]) 317 #define zext_optab (convert_optab_table[CTI_zext]) 318 #define trunc_optab (convert_optab_table[CTI_trunc]) 319 #define sfix_optab (convert_optab_table[CTI_sfix]) 320 #define ufix_optab (convert_optab_table[CTI_ufix]) 321 #define sfixtrunc_optab (convert_optab_table[CTI_sfixtrunc]) 322 #define ufixtrunc_optab (convert_optab_table[CTI_ufixtrunc]) 323 #define sfloat_optab (convert_optab_table[CTI_sfloat]) 324 #define ufloat_optab (convert_optab_table[CTI_ufloat]) 325 326 /* These arrays record the insn_code of insns that may be needed to 327 perform input and output reloads of special objects. They provide a 328 place to pass a scratch register. */ 329 extern enum insn_code reload_in_optab[NUM_MACHINE_MODES]; 330 extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; 331 332 /* Contains the optab used for each rtx code. */ 333 extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1]; 334 335 336 typedef rtx (*rtxfun) (rtx); 337 338 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 339 gives the gen_function to make a branch to test that condition. */ 340 341 extern rtxfun bcc_gen_fctn[NUM_RTX_CODE]; 342 343 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) 344 gives the insn code to make a store-condition insn 345 to test that condition. */ 346 347 extern enum insn_code setcc_gen_code[NUM_RTX_CODE]; 348 349 #ifdef HAVE_conditional_move 350 /* Indexed by the machine mode, gives the insn code to make a conditional 351 move insn. */ 352 353 extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; 354 #endif 355 356 /* This array records the insn_code of insns to perform block moves. */ 357 extern enum insn_code movstr_optab[NUM_MACHINE_MODES]; 358 359 /* This array records the insn_code of insns to perform block clears. */ 360 extern enum insn_code clrstr_optab[NUM_MACHINE_MODES]; 361 362 /* These arrays record the insn_code of two different kinds of insns 363 to perform block compares. */ 364 extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES]; 365 extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES]; 366 367 /* Define functions given in optabs.c. */ 368 369 /* Expand a binary operation given optab and rtx operands. */ 370 extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, 371 enum optab_methods); 372 373 /* Expand a binary operation with both signed and unsigned forms. */ 374 extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx, 375 rtx, int, enum optab_methods); 376 377 /* Generate code to perform an operation on two operands with two results. */ 378 extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int); 379 380 /* Expand a unary arithmetic operation given optab rtx operand. */ 381 extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int); 382 383 /* Expand the absolute value operation. */ 384 extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int); 385 extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int); 386 387 /* Expand the complex absolute value operation. */ 388 extern rtx expand_complex_abs (enum machine_mode, rtx, rtx, int); 389 390 /* Generate an instruction with a given INSN_CODE with an output and 391 an input. */ 392 extern void emit_unop_insn (int, rtx, rtx, enum rtx_code); 393 394 /* Emit code to perform a series of operations on a multi-word quantity, one 395 word at a time. */ 396 extern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx); 397 398 /* Emit one rtl instruction to store zero in specified rtx. */ 399 extern void emit_clr_insn (rtx); 400 401 /* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */ 402 extern void emit_0_to_1_insn (rtx); 403 404 /* Emit one rtl insn to compare two rtx's. */ 405 extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode, 406 int); 407 408 /* The various uses that a comparison can have; used by can_compare_p: 409 jumps, conditional moves, store flag operations. */ 410 enum can_compare_purpose 411 { 412 ccp_jump, 413 ccp_cmov, 414 ccp_store_flag 415 }; 416 417 /* Nonzero if a compare of mode MODE can be done straightforwardly 418 (without splitting it into pieces). */ 419 extern int can_compare_p (enum rtx_code, enum machine_mode, 420 enum can_compare_purpose); 421 422 extern rtx prepare_operand (int, rtx, int, enum machine_mode, 423 enum machine_mode, int); 424 425 /* Return the INSN_CODE to use for an extend operation. */ 426 extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int); 427 428 /* Generate the body of an insn to extend Y (with mode MFROM) 429 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ 430 extern rtx gen_extend_insn (rtx, rtx, enum machine_mode, 431 enum machine_mode, int); 432 433 /* Initialize the tables that control conversion between fixed and 434 floating values. */ 435 extern void init_fixtab (void); 436 extern void init_floattab (void); 437 438 /* Call this to reset the function entry for one optab. */ 439 extern void set_optab_libfunc (optab, enum machine_mode, const char *); 440 extern void set_conv_libfunc (convert_optab, enum machine_mode, 441 enum machine_mode, const char *); 442 443 /* Generate code for a FLOAT_EXPR. */ 444 extern void expand_float (rtx, rtx, int); 445 446 /* Generate code for a FIX_EXPR. */ 447 extern void expand_fix (rtx, rtx, int); 448 449 #endif /* GCC_OPTABS_H */ 450