1 /* Builtins definitions for RISC-V 'V' Extension for GNU compiler. 2 Copyright (C) 2022-2024 Free Software Foundation, Inc. 3 Contributed by Ju-Zhe Zhong (juzhe.zhong (at) rivai.ai), RiVAI Technologies Ltd. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #ifndef GCC_RISCV_VECTOR_BUILTINS_H 22 #define GCC_RISCV_VECTOR_BUILTINS_H 23 24 /* The full name of an RVV intrinsic function is the concatenation of: 25 26 - the base name ("vadd", etc.) 27 - the operand suffix ("_vv", "_vx", etc.) 28 - the type suffix ("_i32m1", "_i32mf2", etc.) 29 - the predication suffix ("_tamu", "_tumu", etc.) 30 31 Each piece of information is individually useful, so we retain this 32 classification throughout: 33 34 - function_base represents the base name. 35 36 - operand_type_index can be used as an index to get operand suffix. 37 38 - rvv_op_info can be used as an index to get argument suffix. 39 40 - predication_type_index can be used as an index to get predication suffix. 41 42 In addition to its unique full name, a function may have a shorter 43 overloaded alias. This alias removes pieces of the suffixes that 44 can be inferred from the arguments, such as by shortening the mode 45 suffix or dropping some of the type suffixes. The base name and the 46 predication suffix stay the same. 47 48 - The function_instance class describes contains all properties of each 49 individual function. Such these information will be used by 50 function_builder, function_base, function_shape, gimple_folder, 51 function_expander, etc. 52 53 - The function_builder class provides several helper function to add an 54 intrinsic function. 55 56 - The function_shape class describes how that instruction has been presented 57 at the language level: 58 59 1. Determine the function name for C and C++ overload function which can 60 be recognized by compiler at language level for each instruction 61 according to members of function_instance (base name, operand suffix, 62 type suffix, predication suffix, etc.). 63 64 2. Specify the arguments type and return type of each function to 65 describe how that instruction has presented at language level. 66 67 - The function_base describes how the underlying instruction behaves. 68 69 The static list of functions uses function_group to describe a group 70 of related functions. The function_builder class is responsible for 71 expanding this static description into a list of individual functions 72 and registering the associated built-in functions. function_instance 73 describes one of these individual functions in terms of the properties 74 described above. 75 76 The classes involved in compiling a function call are: 77 78 - function_resolver, which resolves an overloaded function call to a 79 specific function_instance and its associated function decl. 80 81 - function_checker, which checks whether the values of the arguments 82 conform to the RVV ISA specification. 83 84 - gimple_folder, which tries to fold a function call at the gimple level 85 86 - function_expander, which expands a function call into rtl instructions 87 88 function_resolver and function_checker operate at the language level 89 and so are associated with the function_shape. gimple_folder and 90 function_expander are concerned with the behavior of the function 91 and so are associated with the function_base. */ 92 93 namespace riscv_vector { 94 95 /* Flags that describe what a function might do, in addition to reading 96 its arguments and returning a result. */ 97 static const unsigned int CP_READ_FPCR = 1U << 0; 98 static const unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1; 99 static const unsigned int CP_READ_MEMORY = 1U << 2; 100 static const unsigned int CP_WRITE_MEMORY = 1U << 3; 101 static const unsigned int CP_READ_CSR = 1U << 4; 102 static const unsigned int CP_WRITE_CSR = 1U << 5; 103 104 /* Bit values used to identify required extensions for RVV intrinsics. */ 105 #define RVV_REQUIRE_RV64BIT (1 << 0) /* Require RV64. */ 106 #define RVV_REQUIRE_ELEN_64 (1 << 1) /* Require TARGET_VECTOR_ELEN_64. */ 107 #define RVV_REQUIRE_ELEN_FP_32 (1 << 2) /* Require FP ELEN >= 32. */ 108 #define RVV_REQUIRE_ELEN_FP_64 (1 << 3) /* Require FP ELEN >= 64. */ 109 #define RVV_REQUIRE_FULL_V (1 << 4) /* Require Full 'V' extension. */ 110 #define RVV_REQUIRE_MIN_VLEN_64 (1 << 5) /* Require TARGET_MIN_VLEN >= 64. */ 111 #define RVV_REQUIRE_ELEN_FP_16 (1 << 6) /* Require FP ELEN >= 32. */ 112 113 /* Enumerates the required extensions. */ 114 enum required_ext 115 { 116 VECTOR_EXT, /* Vector extension */ 117 ZVBB_EXT, /* Cryto vector Zvbb sub-ext */ 118 ZVBB_OR_ZVKB_EXT, /* Cryto vector Zvbb or zvkb sub-ext */ 119 ZVBC_EXT, /* Crypto vector Zvbc sub-ext */ 120 ZVKG_EXT, /* Crypto vector Zvkg sub-ext */ 121 ZVKNED_EXT, /* Crypto vector Zvkned sub-ext */ 122 ZVKNHA_OR_ZVKNHB_EXT, /* Crypto vector Zvknh[ab] sub-ext */ 123 ZVKNHB_EXT, /* Crypto vector Zvknhb sub-ext */ 124 ZVKSED_EXT, /* Crypto vector Zvksed sub-ext */ 125 ZVKSH_EXT, /* Crypto vector Zvksh sub-ext */ 126 XTHEADVECTOR_EXT, /* XTheadVector extension */ 127 /* Please update below to isa_name func when add or remove enum type(s). */ 128 }; 129 130 static inline const char * reqired_ext_to_isa_name (enum required_ext required) 131 { 132 switch (required) 133 { 134 case VECTOR_EXT: 135 return "v"; 136 case ZVBB_EXT: 137 return "zvbb"; 138 case ZVBB_OR_ZVKB_EXT: 139 return "zvbb or zvkb"; 140 case ZVBC_EXT: 141 return "zvbc"; 142 case ZVKG_EXT: 143 return "zvkg"; 144 case ZVKNED_EXT: 145 return "zvkned"; 146 case ZVKNHA_OR_ZVKNHB_EXT: 147 return "zvknha or zvknhb"; 148 case ZVKNHB_EXT: 149 return "zvknhb"; 150 case ZVKSED_EXT: 151 return "zvksed"; 152 case ZVKSH_EXT: 153 return "zvksh"; 154 case XTHEADVECTOR_EXT: 155 return "xthreadvector"; 156 default: 157 gcc_unreachable (); 158 } 159 160 gcc_unreachable (); 161 } 162 163 static inline bool required_extensions_specified (enum required_ext required) 164 { 165 switch (required) 166 { 167 case VECTOR_EXT: 168 return TARGET_VECTOR;; 169 case ZVBB_EXT: 170 return TARGET_ZVBB; 171 case ZVBB_OR_ZVKB_EXT: 172 return TARGET_ZVBB || TARGET_ZVKB; 173 case ZVBC_EXT: 174 return TARGET_ZVBC; 175 case ZVKG_EXT: 176 return TARGET_ZVKG; 177 case ZVKNED_EXT: 178 return TARGET_ZVKNED; 179 case ZVKNHA_OR_ZVKNHB_EXT: 180 return TARGET_ZVKNHA || TARGET_ZVKNHB; 181 case ZVKNHB_EXT: 182 return TARGET_ZVKNHB; 183 case ZVKSED_EXT: 184 return TARGET_ZVKSED; 185 case ZVKSH_EXT: 186 return TARGET_ZVKSH; 187 case XTHEADVECTOR_EXT: 188 return TARGET_XTHEADVECTOR; 189 default: 190 gcc_unreachable (); 191 } 192 193 gcc_unreachable (); 194 } 195 196 /* Enumerates the RVV operand types. */ 197 enum operand_type_index 198 { 199 OP_TYPE_none, 200 #define DEF_RVV_OP_TYPE(NAME) OP_TYPE_##NAME, 201 #include "riscv-vector-builtins.def" 202 NUM_OP_TYPES 203 }; 204 205 /* Enumerates the RVV types, together called 206 "vector types" for brevity. */ 207 enum vector_type_index 208 { 209 #define DEF_RVV_TYPE(NAME, ABI_NAME, NCHARS, ARGS...) VECTOR_TYPE_##NAME, 210 #define DEF_RVV_TUPLE_TYPE(NAME, ABI_NAME, NCHARS, ARGS...) VECTOR_TYPE_##NAME, 211 #include "riscv-vector-builtins.def" 212 NUM_VECTOR_TYPES, 213 VECTOR_TYPE_INVALID = NUM_VECTOR_TYPES 214 }; 215 216 /* Enumerates the RVV governing predication types. */ 217 enum predication_type_index 218 { 219 PRED_TYPE_none, 220 #define DEF_RVV_PRED_TYPE(NAME) PRED_TYPE_##NAME, 221 #include "riscv-vector-builtins.def" 222 NUM_PRED_TYPES 223 }; 224 225 /* Enumerates the RVV base types. */ 226 enum rvv_base_type 227 { 228 #define DEF_RVV_BASE_TYPE(NAME, ARGS...) RVV_BASE_##NAME, 229 #include "riscv-vector-builtins.def" 230 NUM_BASE_TYPES 231 }; 232 233 /* Builtin types that are used to register RVV intrinsics. */ 234 struct GTY (()) rvv_builtin_types_t 235 { 236 tree vector; 237 tree scalar; 238 tree vector_ptr; 239 tree scalar_ptr; 240 tree scalar_const_ptr; 241 }; 242 243 /* Builtin suffix that are used to register RVV intrinsics. */ 244 struct rvv_builtin_suffixes 245 { 246 const char *vector; 247 const char *scalar; 248 const char *vsetvl; 249 }; 250 251 /* Builtin base type used to specify the type of builtin function 252 argument or return result. */ 253 struct function_type_info 254 { 255 enum vector_type_index type_indexes[NUM_BASE_TYPES]; 256 }; 257 258 /* RVV Builtin argument information. */ 259 struct rvv_arg_type_info 260 { 261 CONSTEXPR rvv_arg_type_info (rvv_base_type base_type_in) 262 : base_type (base_type_in) 263 {} 264 enum rvv_base_type base_type; 265 266 tree get_scalar_ptr_type (vector_type_index) const; 267 tree get_scalar_const_ptr_type (vector_type_index) const; 268 vector_type_index get_function_type_index (vector_type_index) const; 269 tree get_scalar_type (vector_type_index) const; 270 tree get_vector_type (vector_type_index) const; 271 tree get_tree_type (vector_type_index) const; 272 tree get_tuple_subpart_type (vector_type_index) const; 273 }; 274 275 /* Static information for each operand. */ 276 struct rvv_type_info 277 { 278 enum vector_type_index index; 279 uint64_t required_extensions; 280 }; 281 282 /* RVV Builtin operands information. */ 283 struct rvv_op_info 284 { 285 const rvv_type_info *types; 286 const operand_type_index op; 287 rvv_arg_type_info ret; 288 const rvv_arg_type_info *args; 289 }; 290 291 class registered_function; 292 class function_base; 293 class function_shape; 294 295 /* Static information about a set of functions. */ 296 struct function_group_info 297 { 298 /* Return true if required extension is enabled */ 299 bool match (required_ext ext_value) const 300 { 301 switch (ext_value) 302 { 303 case VECTOR_EXT: 304 return TARGET_VECTOR; 305 case ZVBB_EXT: 306 return TARGET_ZVBB; 307 case ZVBB_OR_ZVKB_EXT: 308 return (TARGET_ZVBB || TARGET_ZVKB); 309 case ZVBC_EXT: 310 return TARGET_ZVBC; 311 case ZVKG_EXT: 312 return TARGET_ZVKG; 313 case ZVKNED_EXT: 314 return TARGET_ZVKNED; 315 case ZVKNHA_OR_ZVKNHB_EXT: 316 return (TARGET_ZVKNHA || TARGET_ZVKNHB); 317 case ZVKNHB_EXT: 318 return TARGET_ZVKNHB; 319 case ZVKSED_EXT: 320 return TARGET_ZVKSED; 321 case ZVKSH_EXT: 322 return TARGET_ZVKSH; 323 case XTHEADVECTOR_EXT: 324 return TARGET_XTHEADVECTOR; 325 default: 326 gcc_unreachable (); 327 } 328 } 329 /* The base name, as a string. */ 330 const char *base_name; 331 332 /* Describes the behavior associated with the function base name. */ 333 const function_base *const *base; 334 335 /* The shape of the functions, as described above the class definition. 336 It's possible to have entries with the same base name but different 337 shapes. */ 338 const function_shape *const *shape; 339 340 /* A list of the available operand types, predication types, 341 and of the available operand datatype. 342 The function supports every combination of the two. 343 The list of predication is terminated by two NUM_PRED_TYPES, 344 while the list of operand info is terminated by NUM_BASE_TYPES. 345 The list of these type suffix is lexicographically ordered based 346 on the index value. */ 347 const predication_type_index *preds; 348 const rvv_op_info ops_infos; 349 /* The required extension value, using it to get the enabled flag. */ 350 required_ext required_extensions; 351 }; 352 353 class GTY ((user)) function_instance 354 { 355 public: 356 function_instance (const char *, const function_base *, 357 const function_shape *, rvv_type_info, 358 predication_type_index, const rvv_op_info *); 359 360 bool operator== (const function_instance &) const; 361 bool operator!= (const function_instance &) const; 362 hashval_t hash () const; 363 364 unsigned int call_properties () const; 365 bool reads_global_state_p () const; 366 bool modifies_global_state_p () const; 367 bool could_trap_p () const; 368 369 /* Return true if return type or arguments are floating point type. */ 370 bool any_type_float_p () const; 371 372 tree get_return_type () const; 373 tree get_arg_type (unsigned opno) const; 374 375 /* The properties of the function. (The explicit "enum"s are required 376 for gengtype.) */ 377 const char *base_name; 378 const function_base *base; 379 const function_shape *shape; 380 rvv_type_info type; 381 enum predication_type_index pred; 382 const rvv_op_info *op_info; 383 }; 384 385 /* A class for building and registering function decls. */ 386 class function_builder 387 { 388 public: 389 function_builder (); 390 ~function_builder (); 391 392 void allocate_argument_types (const function_instance &, vec<tree> &) const; 393 void apply_predication (const function_instance &, tree, vec<tree> &) const; 394 void add_unique_function (const function_instance &, const function_shape *, 395 tree, vec<tree> &, enum required_ext); 396 void add_overloaded_function (const function_instance &, 397 const function_shape *, 398 enum required_ext); 399 void register_function_group (const function_group_info &); 400 void append_name (const char *); 401 void append_base_name (const char *); 402 void append_sew (int); 403 void append_nf (int); 404 char *finish_name (); 405 406 private: 407 tree get_attributes (const function_instance &); 408 409 registered_function &add_function (const function_instance &, const char *, 410 tree, tree, bool, const char *, 411 const vec<tree> &, enum required_ext, 412 bool); 413 414 /* True if we should create a separate decl for each instance of an 415 overloaded function, instead of using function_builder. */ 416 bool m_direct_overloads; 417 418 /* Used for building up function names. */ 419 obstack m_string_obstack; 420 }; 421 422 /* A base class for handling calls to built-in functions. */ 423 class function_call_info : public function_instance 424 { 425 public: 426 function_call_info (location_t, const function_instance &, tree); 427 428 bool function_returns_void_p (); 429 430 /* The location of the call. */ 431 location_t location; 432 433 /* The FUNCTION_DECL that is being called. */ 434 tree fndecl; 435 }; 436 437 /* Return true if the function has no return value. */ 438 inline bool 439 function_call_info::function_returns_void_p () 440 { 441 return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node; 442 } 443 444 /* A class for folding a gimple function call. */ 445 class gimple_folder : public function_call_info 446 { 447 public: 448 gimple_folder (const function_instance &, tree, gimple_stmt_iterator *, 449 gcall *); 450 451 gimple *fold (); 452 453 /* Where to insert extra statements that feed the final replacement. */ 454 gimple_stmt_iterator *gsi; 455 456 /* The call we're folding. */ 457 gcall *call; 458 459 /* The result of the call, or null if none. */ 460 tree lhs; 461 }; 462 463 /* A class for expanding a function call into RTL. */ 464 class function_expander : public function_call_info 465 { 466 public: 467 function_expander (const function_instance &, tree, tree, rtx); 468 rtx expand (); 469 470 void add_input_operand (machine_mode, rtx); 471 void add_input_operand (unsigned); 472 void add_output_operand (machine_mode, rtx); 473 void add_all_one_mask_operand (machine_mode); 474 void add_scalar_move_mask_operand (machine_mode); 475 void add_vundef_operand (machine_mode); 476 void add_fixed_operand (rtx); 477 void add_integer_operand (rtx); 478 void add_mem_operand (machine_mode, unsigned); 479 480 machine_mode vector_mode (void) const; 481 machine_mode index_mode (void) const; 482 machine_mode arg_mode (int) const; 483 machine_mode mask_mode (void) const; 484 machine_mode ret_mode (void) const; 485 486 rtx use_exact_insn (insn_code); 487 rtx use_contiguous_load_insn (insn_code); 488 rtx use_contiguous_store_insn (insn_code); 489 rtx use_compare_insn (rtx_code, insn_code); 490 rtx use_ternop_insn (bool, insn_code); 491 rtx use_widen_ternop_insn (insn_code); 492 rtx use_scalar_move_insn (insn_code); 493 rtx generate_insn (insn_code); 494 495 /* The function call expression. */ 496 tree exp; 497 498 /* For functions that return a value, this is the preferred location 499 of that value. It could be null or could have a different mode 500 from the function return type. */ 501 rtx target; 502 503 /* The number of the operands. */ 504 int opno; 505 506 private: 507 /* Used to build up the operands to an instruction. */ 508 struct expand_operand m_ops[MAX_RECOG_OPERANDS]; 509 }; 510 511 /* Provides information about a particular function base name, and handles 512 tasks related to the base name. */ 513 class function_base 514 { 515 public: 516 /* Return a set of CP_* flags that describe what the function might do, 517 in addition to reading its arguments and returning a result. */ 518 virtual unsigned int call_properties (const function_instance &) const; 519 520 /* Return true if intrinsics should apply vl operand. */ 521 virtual bool apply_vl_p () const; 522 523 /* Return true if intrinsics should apply tail policy operand. */ 524 virtual bool apply_tail_policy_p () const; 525 526 /* Return true if intrinsics should apply mask policy operand. */ 527 virtual bool apply_mask_policy_p () const; 528 529 /* Return true if intrinsic can be overloaded. */ 530 virtual bool can_be_overloaded_p (enum predication_type_index) const; 531 532 /* Return true if intrinsics use mask predication. */ 533 virtual bool use_mask_predication_p () const; 534 535 /* Return true if intrinsics has merge operand. */ 536 virtual bool has_merge_operand_p () const; 537 538 /* Return true if intrinsics has rounding mode operand. */ 539 virtual bool has_rounding_mode_operand_p () const; 540 541 /* Return true if intrinsics maybe require vxrm operand. */ 542 virtual bool may_require_vxrm_p () const; 543 544 /* Return true if intrinsics maybe require frm operand. */ 545 virtual bool may_require_frm_p () const; 546 547 /* Try to fold the given gimple call. Return the new gimple statement 548 on success, otherwise return null. */ 549 virtual gimple *fold (gimple_folder &) const { return NULL; } 550 551 /* Expand the given call into rtl. Return the result of the function, 552 or an arbitrary value if the function doesn't return a result. */ 553 virtual rtx expand (function_expander &) const = 0; 554 }; 555 556 /* A class for checking that the semantic constraints on a function call are 557 satisfied, such as arguments being integer constant expressions with 558 a particular range. The parent class's FNDECL is the decl that was 559 called in the original source, before overload resolution. */ 560 class function_checker : public function_call_info 561 { 562 public: 563 function_checker (location_t, const function_instance &, tree, tree, 564 unsigned int, tree *); 565 566 machine_mode arg_mode (unsigned int) const; 567 machine_mode ret_mode (void) const; 568 unsigned int arg_num (void) const; 569 bool check (void); 570 571 bool require_immediate (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT) const; 572 bool require_immediate_range_or (unsigned int, HOST_WIDE_INT, 573 HOST_WIDE_INT, HOST_WIDE_INT) const; 574 575 private: 576 bool require_immediate_range (unsigned int, HOST_WIDE_INT, 577 HOST_WIDE_INT) const; 578 void report_non_ice (unsigned int) const; 579 void report_out_of_range (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT, 580 HOST_WIDE_INT) const; 581 void report_out_of_range_and_not (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT, 582 HOST_WIDE_INT, HOST_WIDE_INT) const; 583 584 /* The type of the resolved function. */ 585 tree m_fntype; 586 587 /* The arguments to the function. */ 588 unsigned int m_nargs; 589 tree *m_args; 590 }; 591 592 /* Classifies functions into "shapes" base on: 593 594 - Base name of the intrinsic function. 595 596 - Operand types list. 597 598 - Argument type list. 599 600 - Predication type list. */ 601 class function_shape 602 { 603 public: 604 /* Shape the function name according to function_instance. */ 605 virtual char *get_name (function_builder &, const function_instance &, 606 bool) const 607 = 0; 608 609 /* Define all functions associated with the given group. */ 610 virtual void build (function_builder &, const function_group_info &) const 611 = 0; 612 613 /* Check whether the given call is semantically valid. Return true 614 if it is, otherwise report an error and return false. */ 615 virtual bool check (function_checker &) const { return true; } 616 }; 617 618 extern const char *const operand_suffixes[NUM_OP_TYPES]; 619 extern const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1]; 620 extern const char *const predication_suffixes[NUM_PRED_TYPES]; 621 extern rvv_builtin_types_t builtin_types[NUM_VECTOR_TYPES + 1]; 622 extern function_instance get_read_vl_instance (void); 623 extern tree get_read_vl_decl (void); 624 625 inline tree 626 rvv_arg_type_info::get_scalar_type (vector_type_index type_idx) const 627 { 628 return get_function_type_index (type_idx) == VECTOR_TYPE_INVALID 629 ? NULL_TREE 630 : builtin_types[get_function_type_index (type_idx)].scalar; 631 } 632 633 inline tree 634 rvv_arg_type_info::get_vector_type (vector_type_index type_idx) const 635 { 636 return get_function_type_index (type_idx) == VECTOR_TYPE_INVALID 637 ? NULL_TREE 638 : builtin_types[get_function_type_index (type_idx)].vector; 639 } 640 641 inline bool 642 function_instance::operator!= (const function_instance &other) const 643 { 644 return !operator== (other); 645 } 646 647 /* Expand the call and return its lhs. */ 648 inline rtx 649 function_expander::expand () 650 { 651 return base->expand (*this); 652 } 653 654 /* Create op and add it into M_OPS and increase OPNO. */ 655 inline void 656 function_expander::add_input_operand (machine_mode mode, rtx op) 657 { 658 create_input_operand (&m_ops[opno++], op, mode); 659 } 660 661 /* Create output and add it into M_OPS and increase OPNO. */ 662 inline void 663 function_expander::add_output_operand (machine_mode mode, rtx target) 664 { 665 create_output_operand (&m_ops[opno++], target, mode); 666 } 667 668 /* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter. 669 We add a fake all true mask for the intrinsics that don't need a real mask. 670 */ 671 inline void 672 function_expander::add_all_one_mask_operand (machine_mode mode) 673 { 674 add_input_operand (mode, CONSTM1_RTX (mode)); 675 } 676 677 /* Add mask operand for scalar move instruction. */ 678 inline void 679 function_expander::add_scalar_move_mask_operand (machine_mode mode) 680 { 681 add_input_operand (mode, gen_scalar_move_mask (mode)); 682 } 683 684 /* Add an operand that must be X. The only way of legitimizing an 685 invalid X is to reload the address of a MEM. */ 686 inline void 687 function_expander::add_fixed_operand (rtx x) 688 { 689 create_fixed_operand (&m_ops[opno++], x); 690 } 691 692 /* Add an integer operand X. */ 693 inline void 694 function_expander::add_integer_operand (rtx x) 695 { 696 create_integer_operand (&m_ops[opno++], INTVAL (x)); 697 } 698 699 /* Return the machine_mode of the corresponding vector type. */ 700 inline machine_mode 701 function_expander::vector_mode (void) const 702 { 703 return TYPE_MODE (builtin_types[type.index].vector); 704 } 705 706 /* Return the machine_mode of the corresponding index type. */ 707 inline machine_mode 708 function_expander::index_mode (void) const 709 { 710 return TYPE_MODE (op_info->args[1].get_tree_type (type.index)); 711 } 712 713 /* Return the machine_mode of the corresponding arg type. */ 714 inline machine_mode 715 function_expander::arg_mode (int idx) const 716 { 717 return TYPE_MODE (op_info->args[idx].get_tree_type (type.index)); 718 } 719 720 /* Return the machine_mode of the corresponding return type. */ 721 inline machine_mode 722 function_expander::ret_mode (void) const 723 { 724 return TYPE_MODE (op_info->ret.get_tree_type (type.index)); 725 } 726 727 inline machine_mode 728 function_checker::arg_mode (unsigned int argno) const 729 { 730 return TYPE_MODE (TREE_TYPE (m_args[argno])); 731 } 732 733 inline machine_mode 734 function_checker::ret_mode () const 735 { 736 return TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))); 737 } 738 739 inline unsigned int 740 function_checker::arg_num () const 741 { 742 return m_nargs; 743 } 744 745 /* Default implementation of function_base::call_properties, with conservatively 746 correct behavior for floating-point instructions. */ 747 inline unsigned int 748 function_base::call_properties (const function_instance &instance) const 749 { 750 unsigned int flags = 0; 751 if (instance.any_type_float_p ()) 752 return flags | CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS; 753 return flags; 754 } 755 756 /* We choose to apply vl operand by default since most of the intrinsics 757 has vl operand. */ 758 inline bool 759 function_base::apply_vl_p () const 760 { 761 return true; 762 } 763 764 /* We choose to apply tail policy operand by default since most of the 765 intrinsics has tail policy operand. */ 766 inline bool 767 function_base::apply_tail_policy_p () const 768 { 769 return true; 770 } 771 772 /* We choose to apply mask policy operand by default since most of the 773 intrinsics has mask policy operand. */ 774 inline bool 775 function_base::apply_mask_policy_p () const 776 { 777 return true; 778 } 779 780 /* We choose to return true by default since most of the intrinsics use 781 mask predication. */ 782 inline bool 783 function_base::use_mask_predication_p () const 784 { 785 return true; 786 } 787 788 /* We choose to return true by default since most of the intrinsics use 789 has merge operand. */ 790 inline bool 791 function_base::has_merge_operand_p () const 792 { 793 return true; 794 } 795 796 /* We choose to return false by default since most of the intrinsics does 797 not have rounding mode operand. */ 798 inline bool 799 function_base::has_rounding_mode_operand_p () const 800 { 801 return false; 802 } 803 804 /* We choose to return false by default since most of the intrinsics does 805 not need frm operand. */ 806 inline bool 807 function_base::may_require_frm_p () const 808 { 809 return false; 810 } 811 812 /* We choose to return false by default since most of the intrinsics does 813 not need vxrm operand. */ 814 inline bool 815 function_base::may_require_vxrm_p () const 816 { 817 return false; 818 } 819 820 /* Since most of intrinsics can be overloaded, we set it true by default. */ 821 inline bool 822 function_base::can_be_overloaded_p (enum predication_type_index) const 823 { 824 return true; 825 } 826 827 /* Return the single field in tuple type TYPE. */ 828 inline tree 829 tuple_type_field (tree type) 830 { 831 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 832 if (TREE_CODE (field) == FIELD_DECL) 833 return field; 834 gcc_unreachable (); 835 } 836 837 } // end namespace riscv_vector 838 839 #endif 840