1/* Definitions for code generation pass of GNU compiler. 2 Copyright (C) 2001-2015 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 3, or (at your option) 9any later version. 10 11GCC is distributed in the hope that it will be useful, 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 17along with GCC; see the file COPYING3. If not see 18<http://www.gnu.org/licenses/>. */ 19 20#ifndef GCC_OPTABS_H 21#define GCC_OPTABS_H 22 23#include "insn-opinit.h" 24 25/* Generate code for a widening multiply. */ 26extern rtx expand_widening_mult (machine_mode, rtx, rtx, rtx, int, optab); 27 28/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing 29 if the target does not have such an insn. */ 30 31static inline enum insn_code 32optab_handler (optab op, machine_mode mode) 33{ 34 unsigned scode = (op << 16) | mode; 35 gcc_assert (op > LAST_CONV_OPTAB); 36 return raw_optab_handler (scode); 37} 38 39/* Return the insn used to perform conversion OP from mode FROM_MODE 40 to mode TO_MODE; return CODE_FOR_nothing if the target does not have 41 such an insn. */ 42 43static inline enum insn_code 44convert_optab_handler (convert_optab op, machine_mode to_mode, 45 machine_mode from_mode) 46{ 47 unsigned scode = (op << 16) | (from_mode << 8) | to_mode; 48 gcc_assert (op > unknown_optab && op <= LAST_CONV_OPTAB); 49 return raw_optab_handler (scode); 50} 51 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 55static inline enum insn_code 56direct_optab_handler (direct_optab op, machine_mode mode) 57{ 58 return optab_handler (op, mode); 59} 60 61/* Return true if UNOPTAB is for a trapping-on-overflow operation. */ 62 63static inline bool 64trapv_unoptab_p (optab unoptab) 65{ 66 return (unoptab == negv_optab 67 || unoptab == absv_optab); 68} 69 70/* Return true if BINOPTAB is for a trapping-on-overflow operation. */ 71 72static inline bool 73trapv_binoptab_p (optab binoptab) 74{ 75 return (binoptab == addv_optab 76 || binoptab == subv_optab 77 || binoptab == smulv_optab); 78} 79 80 81 82/* Describes an instruction that inserts or extracts a bitfield. */ 83struct extraction_insn 84{ 85 /* The code of the instruction. */ 86 enum insn_code icode; 87 88 /* The mode that the structure operand should have. This is byte_mode 89 when using the legacy insv, extv and extzv patterns to access memory. */ 90 machine_mode struct_mode; 91 92 /* The mode of the field to be inserted or extracted, and by extension 93 the mode of the insertion or extraction itself. */ 94 machine_mode field_mode; 95 96 /* The mode of the field's bit position. This is only important 97 when the position is variable rather than constant. */ 98 machine_mode pos_mode; 99}; 100 101 102 103 104/* Describes the type of an expand_operand. Each value is associated 105 with a create_*_operand function; see the comments above those 106 functions for details. */ 107enum expand_operand_type { 108 EXPAND_FIXED, 109 EXPAND_OUTPUT, 110 EXPAND_INPUT, 111 EXPAND_CONVERT_TO, 112 EXPAND_CONVERT_FROM, 113 EXPAND_ADDRESS, 114 EXPAND_INTEGER 115}; 116 117/* Information about an operand for instruction expansion. */ 118struct expand_operand { 119 /* The type of operand. */ 120 ENUM_BITFIELD (expand_operand_type) type : 8; 121 122 /* True if any conversion should treat VALUE as being unsigned 123 rather than signed. Only meaningful for certain types. */ 124 unsigned int unsigned_p : 1; 125 126 /* Unused; available for future use. */ 127 unsigned int unused : 7; 128 129 /* The mode passed to the convert_*_operand function. It has a 130 type-dependent meaning. */ 131 ENUM_BITFIELD (machine_mode) mode : 16; 132 133 /* The value of the operand. */ 134 rtx value; 135}; 136 137/* Initialize OP with the given fields. Initialise the other fields 138 to their default values. */ 139 140static inline void 141create_expand_operand (struct expand_operand *op, 142 enum expand_operand_type type, 143 rtx value, machine_mode mode, 144 bool unsigned_p) 145{ 146 op->type = type; 147 op->unsigned_p = unsigned_p; 148 op->unused = 0; 149 op->mode = mode; 150 op->value = value; 151} 152 153/* Make OP describe an operand that must use rtx X, even if X is volatile. */ 154 155static inline void 156create_fixed_operand (struct expand_operand *op, rtx x) 157{ 158 create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false); 159} 160 161/* Make OP describe an output operand that must have mode MODE. 162 X, if nonnull, is a suggestion for where the output should be stored. 163 It is OK for VALUE to be inconsistent with MODE, although it will just 164 be ignored in that case. */ 165 166static inline void 167create_output_operand (struct expand_operand *op, rtx x, 168 machine_mode mode) 169{ 170 create_expand_operand (op, EXPAND_OUTPUT, x, mode, false); 171} 172 173/* Make OP describe an input operand that must have mode MODE and 174 value VALUE; MODE cannot be VOIDmode. The backend may request that 175 VALUE be copied into a different kind of rtx before being passed 176 as an operand. */ 177 178static inline void 179create_input_operand (struct expand_operand *op, rtx value, 180 machine_mode mode) 181{ 182 create_expand_operand (op, EXPAND_INPUT, value, mode, false); 183} 184 185/* Like create_input_operand, except that VALUE must first be converted 186 to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */ 187 188static inline void 189create_convert_operand_to (struct expand_operand *op, rtx value, 190 machine_mode mode, bool unsigned_p) 191{ 192 create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p); 193} 194 195/* Make OP describe an input operand that should have the same value 196 as VALUE, after any mode conversion that the backend might request. 197 If VALUE is a CONST_INT, it should be treated as having mode MODE. 198 UNSIGNED_P says whether VALUE is unsigned. */ 199 200static inline void 201create_convert_operand_from (struct expand_operand *op, rtx value, 202 machine_mode mode, bool unsigned_p) 203{ 204 create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p); 205} 206 207 208/* Make OP describe an input Pmode address operand. VALUE is the value 209 of the address, but it may need to be converted to Pmode first. */ 210 211static inline void 212create_address_operand (struct expand_operand *op, rtx value) 213{ 214 create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false); 215} 216 217/* Make OP describe an input operand that has value INTVAL and that has 218 no inherent mode. This function should only be used for operands that 219 are always expand-time constants. The backend may request that INTVAL 220 be copied into a different kind of rtx, but it must specify the mode 221 of that rtx if so. */ 222 223static inline void 224create_integer_operand (struct expand_operand *op, HOST_WIDE_INT intval) 225{ 226 create_expand_operand (op, EXPAND_INTEGER, GEN_INT (intval), VOIDmode, false); 227} 228 229 230extern rtx convert_optab_libfunc (convert_optab optab, machine_mode mode1, 231 machine_mode mode2); 232extern rtx optab_libfunc (optab optab, machine_mode mode); 233extern enum insn_code widening_optab_handler (optab, machine_mode, 234 machine_mode); 235/* Find a widening optab even if it doesn't widen as much as we want. */ 236#define find_widening_optab_handler(A,B,C,D) \ 237 find_widening_optab_handler_and_mode (A, B, C, D, NULL) 238extern enum insn_code find_widening_optab_handler_and_mode (optab, 239 machine_mode, 240 machine_mode, 241 int, 242 machine_mode *); 243 244/* An extra flag to control optab_for_tree_code's behavior. This is needed to 245 distinguish between machines with a vector shift that takes a scalar for the 246 shift amount vs. machines that take a vector for the shift amount. */ 247enum optab_subtype 248{ 249 optab_default, 250 optab_scalar, 251 optab_vector 252}; 253 254/* Passed to expand_simple_binop and expand_binop to say which options 255 to try to use if the requested operation can't be open-coded on the 256 requisite mode. Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using 257 a library call. Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try 258 using a wider mode. OPTAB_MUST_WIDEN says try widening and don't 259 try anything else. */ 260 261enum optab_methods 262{ 263 OPTAB_DIRECT, 264 OPTAB_LIB, 265 OPTAB_WIDEN, 266 OPTAB_LIB_WIDEN, 267 OPTAB_MUST_WIDEN 268}; 269 270/* Return the optab used for computing the given operation on the type given by 271 the second argument. The third argument distinguishes between the types of 272 vector shifts and rotates */ 273extern optab optab_for_tree_code (enum tree_code, const_tree, enum optab_subtype); 274 275/* Given an optab that reduces a vector to a scalar, find instead the old 276 optab that produces a vector with the reduction result in one element, 277 for a tree with the specified type. */ 278extern optab scalar_reduc_to_vector (optab, const_tree type); 279 280extern rtx expand_widen_pattern_expr (struct separate_ops *, rtx , rtx , rtx, 281 rtx, int); 282extern rtx expand_ternary_op (machine_mode mode, optab ternary_optab, 283 rtx op0, rtx op1, rtx op2, rtx target, 284 int unsignedp); 285extern rtx simplify_expand_binop (machine_mode mode, optab binoptab, 286 rtx op0, rtx op1, rtx target, int unsignedp, 287 enum optab_methods methods); 288extern bool force_expand_binop (machine_mode, optab, rtx, rtx, rtx, int, 289 enum optab_methods); 290 291/* Generate code for a simple binary or unary operation. "Simple" in 292 this case means "can be unambiguously described by a (mode, code) 293 pair and mapped to a single optab." */ 294extern rtx expand_simple_binop (machine_mode, enum rtx_code, rtx, 295 rtx, rtx, int, enum optab_methods); 296 297/* Expand a binary operation given optab and rtx operands. */ 298extern rtx expand_binop (machine_mode, optab, rtx, rtx, rtx, int, 299 enum optab_methods); 300 301/* Expand a binary operation with both signed and unsigned forms. */ 302extern rtx sign_expand_binop (machine_mode, optab, optab, rtx, rtx, 303 rtx, int, enum optab_methods); 304 305/* Generate code to perform an operation on one operand with two results. */ 306extern int expand_twoval_unop (optab, rtx, rtx, rtx, int); 307 308/* Generate code to perform an operation on two operands with two results. */ 309extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int); 310 311/* Generate code to perform an operation on two operands with two 312 results, using a library function. */ 313extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, 314 enum rtx_code); 315extern rtx expand_simple_unop (machine_mode, enum rtx_code, rtx, rtx, 316 int); 317 318/* Expand a unary arithmetic operation given optab rtx operand. */ 319extern rtx expand_unop (machine_mode, optab, rtx, rtx, int); 320 321/* Expand the absolute value operation. */ 322extern rtx expand_abs_nojump (machine_mode, rtx, rtx, int); 323extern rtx expand_abs (machine_mode, rtx, rtx, int, int); 324 325/* Expand the one's complement absolute value operation. */ 326extern rtx expand_one_cmpl_abs_nojump (machine_mode, rtx, rtx); 327 328/* Expand the copysign operation. */ 329extern rtx expand_copysign (rtx, rtx, rtx); 330/* Generate an instruction with a given INSN_CODE with an output and 331 an input. */ 332extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code); 333extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code); 334 335/* Emit code to make a call to a constant function or a library call. */ 336extern void emit_libcall_block (rtx, rtx, rtx, rtx); 337 338/* The various uses that a comparison can have; used by can_compare_p: 339 jumps, conditional moves, store flag operations. */ 340enum can_compare_purpose 341{ 342 ccp_jump, 343 ccp_cmov, 344 ccp_store_flag 345}; 346 347/* Nonzero if a compare of mode MODE can be done straightforwardly 348 (without splitting it into pieces). */ 349extern int can_compare_p (enum rtx_code, machine_mode, 350 enum can_compare_purpose); 351extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode, 352 machine_mode, int); 353/* Emit a pair of rtl insns to compare two rtx's and to jump 354 to a label if the comparison is true. */ 355extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx, 356 machine_mode, int, rtx, int prob=-1); 357 358/* Generate code to indirectly jump to a location given in the rtx LOC. */ 359extern void emit_indirect_jump (rtx); 360 361#include "insn-config.h" 362 363#ifndef GCC_INSN_CONFIG_H 364#error "insn-config.h must be included before optabs.h" 365#endif 366 367#ifdef HAVE_conditional_move 368/* Emit a conditional move operation. */ 369rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode, 370 rtx, rtx, machine_mode, int); 371 372/* Return nonzero if the conditional move is supported. */ 373int can_conditionally_move_p (machine_mode mode); 374 375#endif 376rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, machine_mode, 377 rtx, rtx, machine_mode, int); 378 379/* Create but don't emit one rtl instruction to perform certain operations. 380 Modes must match; operands must meet the operation's predicates. 381 Likewise for subtraction and for just copying. */ 382extern rtx gen_add2_insn (rtx, rtx); 383extern rtx gen_add3_insn (rtx, rtx, rtx); 384extern int have_add2_insn (rtx, rtx); 385extern rtx gen_addptr3_insn (rtx, rtx, rtx); 386extern int have_addptr3_insn (rtx, rtx, rtx); 387extern rtx gen_sub2_insn (rtx, rtx); 388extern rtx gen_sub3_insn (rtx, rtx, rtx); 389extern int have_sub2_insn (rtx, rtx); 390 391/* Return the INSN_CODE to use for an extend operation. */ 392extern enum insn_code can_extend_p (machine_mode, machine_mode, int); 393 394/* Generate the body of an insn to extend Y (with mode MFROM) 395 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ 396extern rtx gen_extend_insn (rtx, rtx, machine_mode, 397 machine_mode, int); 398 399/* Return the insn_code for a FLOAT_EXPR. */ 400enum insn_code can_float_p (machine_mode, machine_mode, int); 401 402/* Check whether an operation represented by the code CODE is a 403 convert operation that is supported by the target platform in 404 vector form */ 405bool supportable_convert_operation (enum tree_code, tree, tree, tree *, 406 enum tree_code *); 407 408/* Generate code for a FLOAT_EXPR. */ 409extern void expand_float (rtx, rtx, int); 410 411/* Generate code for a FIX_EXPR. */ 412extern void expand_fix (rtx, rtx, int); 413 414/* Generate code for a FIXED_CONVERT_EXPR. */ 415extern void expand_fixed_convert (rtx, rtx, int, int); 416 417/* Generate code for float to integral conversion. */ 418extern bool expand_sfix_optab (rtx, rtx, convert_optab); 419 420/* Report whether the machine description contains an insn which can 421 perform the operation described by CODE and MODE. */ 422extern int have_insn_for (enum rtx_code, machine_mode); 423 424extern void gen_int_libfunc (optab, const char *, char, machine_mode); 425extern void gen_fp_libfunc (optab, const char *, char, machine_mode); 426extern void gen_fixed_libfunc (optab, const char *, char, machine_mode); 427extern void gen_signed_fixed_libfunc (optab, const char *, char, 428 machine_mode); 429extern void gen_unsigned_fixed_libfunc (optab, const char *, char, 430 machine_mode); 431extern void gen_int_fp_libfunc (optab, const char *, char, machine_mode); 432extern void gen_intv_fp_libfunc (optab, const char *, char, machine_mode); 433extern void gen_int_fp_fixed_libfunc (optab, const char *, char, 434 machine_mode); 435extern void gen_int_fp_signed_fixed_libfunc (optab, const char *, char, 436 machine_mode); 437extern void gen_int_fixed_libfunc (optab, const char *, char, 438 machine_mode); 439extern void gen_int_signed_fixed_libfunc (optab, const char *, char, 440 machine_mode); 441extern void gen_int_unsigned_fixed_libfunc (optab, const char *, char, 442 machine_mode); 443 444extern void gen_interclass_conv_libfunc (convert_optab, const char *, 445 machine_mode, machine_mode); 446extern void gen_int_to_fp_conv_libfunc (convert_optab, const char *, 447 machine_mode, machine_mode); 448extern void gen_ufloat_conv_libfunc (convert_optab, const char *, 449 machine_mode, machine_mode); 450extern void gen_int_to_fp_nondecimal_conv_libfunc (convert_optab, 451 const char *, 452 machine_mode, 453 machine_mode); 454extern void gen_fp_to_int_conv_libfunc (convert_optab, const char *, 455 machine_mode, machine_mode); 456extern void gen_intraclass_conv_libfunc (convert_optab, const char *, 457 machine_mode, machine_mode); 458extern void gen_trunc_conv_libfunc (convert_optab, const char *, 459 machine_mode, machine_mode); 460extern void gen_extend_conv_libfunc (convert_optab, const char *, 461 machine_mode, machine_mode); 462extern void gen_fract_conv_libfunc (convert_optab, const char *, 463 machine_mode, machine_mode); 464extern void gen_fractuns_conv_libfunc (convert_optab, const char *, 465 machine_mode, machine_mode); 466extern void gen_satfract_conv_libfunc (convert_optab, const char *, 467 machine_mode, machine_mode); 468extern void gen_satfractuns_conv_libfunc (convert_optab, const char *, 469 machine_mode, 470 machine_mode); 471 472/* Build a decl for a libfunc named NAME. */ 473extern tree build_libfunc_function (const char *); 474 475/* Call this to initialize an optab function entry. */ 476extern rtx init_one_libfunc (const char *); 477extern rtx set_user_assembler_libfunc (const char *, const char *); 478 479/* Call this to reset the function entry for one optab. */ 480extern void set_optab_libfunc (optab, machine_mode, const char *); 481extern void set_conv_libfunc (convert_optab, machine_mode, 482 machine_mode, const char *); 483 484/* Call this once to initialize the contents of the optabs 485 appropriately for the current target machine. */ 486extern void init_optabs (void); 487extern void init_tree_optimization_optabs (tree); 488 489/* Call this to install all of the __sync libcalls up to size MAX. */ 490extern void init_sync_libfuncs (int max); 491 492/* Generate a conditional trap instruction. */ 493extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx); 494 495/* Return true if target supports vector operations for VEC_PERM_EXPR. */ 496extern bool can_vec_perm_p (machine_mode, bool, const unsigned char *); 497 498/* Generate code for VEC_PERM_EXPR. */ 499extern rtx expand_vec_perm (machine_mode, rtx, rtx, rtx, rtx); 500 501/* Return tree if target supports vector operations for COND_EXPR. */ 502bool expand_vec_cond_expr_p (tree, tree); 503 504/* Generate code for VEC_COND_EXPR. */ 505extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx); 506 507/* Return non-zero if target supports a given highpart multiplication. */ 508extern int can_mult_highpart_p (machine_mode, bool); 509 510/* Generate code for MULT_HIGHPART_EXPR. */ 511extern rtx expand_mult_highpart (machine_mode, rtx, rtx, rtx, bool); 512 513/* Return true if target supports vector masked load/store for mode. */ 514extern bool can_vec_mask_load_store_p (machine_mode, bool); 515 516/* Return true if there is an inline compare and swap pattern. */ 517extern bool can_compare_and_swap_p (machine_mode, bool); 518 519/* Return true if there is an inline atomic exchange pattern. */ 520extern bool can_atomic_exchange_p (machine_mode, bool); 521 522extern rtx expand_sync_lock_test_and_set (rtx, rtx, rtx); 523extern rtx expand_atomic_test_and_set (rtx, rtx, enum memmodel); 524extern rtx expand_atomic_exchange (rtx, rtx, rtx, enum memmodel); 525extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool, 526 enum memmodel, enum memmodel); 527/* Generate memory barriers. */ 528extern void expand_mem_thread_fence (enum memmodel); 529extern void expand_mem_signal_fence (enum memmodel); 530 531rtx expand_atomic_load (rtx, rtx, enum memmodel); 532rtx expand_atomic_store (rtx, rtx, enum memmodel, bool); 533rtx expand_atomic_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel, 534 bool); 535 536extern bool insn_operand_matches (enum insn_code icode, unsigned int opno, 537 rtx operand); 538extern bool valid_multiword_target_p (rtx); 539extern void create_convert_operand_from_type (struct expand_operand *op, 540 rtx value, tree type); 541extern bool maybe_legitimize_operands (enum insn_code icode, 542 unsigned int opno, unsigned int nops, 543 struct expand_operand *ops); 544extern rtx maybe_gen_insn (enum insn_code icode, unsigned int nops, 545 struct expand_operand *ops); 546extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops, 547 struct expand_operand *ops); 548extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops, 549 struct expand_operand *ops); 550extern void expand_insn (enum insn_code icode, unsigned int nops, 551 struct expand_operand *ops); 552extern void expand_jump_insn (enum insn_code icode, unsigned int nops, 553 struct expand_operand *ops); 554 555/* Enumerates the possible extraction_insn operations. */ 556enum extraction_pattern { EP_insv, EP_extv, EP_extzv }; 557 558extern bool get_best_reg_extraction_insn (extraction_insn *, 559 enum extraction_pattern, 560 unsigned HOST_WIDE_INT, 561 machine_mode); 562extern bool get_best_mem_extraction_insn (extraction_insn *, 563 enum extraction_pattern, 564 HOST_WIDE_INT, HOST_WIDE_INT, 565 machine_mode); 566 567extern bool lshift_cheap_p (bool); 568 569extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp); 570 571#endif /* GCC_OPTABS_H */ 572