1c2b8dc6dSmatt;; Predicate description for RISC-V target. 2*2f055536Smrg;; Copyright (C) 2011-2020 Free Software Foundation, Inc. 36a5c9aabSmrg;; Contributed by Andrew Waterman (andrew@sifive.com). 4c2b8dc6dSmatt;; Based on MIPS target for GNU compiler. 5c2b8dc6dSmatt;; 6c2b8dc6dSmatt;; This file is part of GCC. 7c2b8dc6dSmatt;; 8c2b8dc6dSmatt;; GCC is free software; you can redistribute it and/or modify 9c2b8dc6dSmatt;; it under the terms of the GNU General Public License as published by 10c2b8dc6dSmatt;; the Free Software Foundation; either version 3, or (at your option) 11c2b8dc6dSmatt;; any later version. 12c2b8dc6dSmatt;; 13c2b8dc6dSmatt;; GCC is distributed in the hope that it will be useful, 14c2b8dc6dSmatt;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15c2b8dc6dSmatt;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16c2b8dc6dSmatt;; GNU General Public License for more details. 17c2b8dc6dSmatt;; 18c2b8dc6dSmatt;; You should have received a copy of the GNU General Public License 19c2b8dc6dSmatt;; along with GCC; see the file COPYING3. If not see 20c2b8dc6dSmatt;; <http://www.gnu.org/licenses/>. 21c2b8dc6dSmatt 22c2b8dc6dSmatt(define_predicate "const_arith_operand" 23c2b8dc6dSmatt (and (match_code "const_int") 24c2b8dc6dSmatt (match_test "SMALL_OPERAND (INTVAL (op))"))) 25c2b8dc6dSmatt 26c2b8dc6dSmatt(define_predicate "arith_operand" 27c2b8dc6dSmatt (ior (match_operand 0 "const_arith_operand") 28c2b8dc6dSmatt (match_operand 0 "register_operand"))) 29c2b8dc6dSmatt 30*2f055536Smrg(define_predicate "lui_operand" 31*2f055536Smrg (and (match_code "const_int") 32*2f055536Smrg (match_test "LUI_OPERAND (INTVAL (op))"))) 33*2f055536Smrg 34*2f055536Smrg(define_predicate "sfb_alu_operand" 35*2f055536Smrg (ior (match_operand 0 "arith_operand") 36*2f055536Smrg (match_operand 0 "lui_operand"))) 37*2f055536Smrg 386a5c9aabSmrg(define_predicate "const_csr_operand" 396a5c9aabSmrg (and (match_code "const_int") 406a5c9aabSmrg (match_test "IN_RANGE (INTVAL (op), 0, 31)"))) 416a5c9aabSmrg 426a5c9aabSmrg(define_predicate "csr_operand" 436a5c9aabSmrg (ior (match_operand 0 "const_csr_operand") 446a5c9aabSmrg (match_operand 0 "register_operand"))) 456a5c9aabSmrg 46c2b8dc6dSmatt(define_predicate "sle_operand" 47c2b8dc6dSmatt (and (match_code "const_int") 48c2b8dc6dSmatt (match_test "SMALL_OPERAND (INTVAL (op) + 1)"))) 49c2b8dc6dSmatt 50c2b8dc6dSmatt(define_predicate "sleu_operand" 51c2b8dc6dSmatt (and (match_operand 0 "sle_operand") 52c2b8dc6dSmatt (match_test "INTVAL (op) + 1 != 0"))) 53c2b8dc6dSmatt 54c2b8dc6dSmatt(define_predicate "const_0_operand" 556a5c9aabSmrg (and (match_code "const_int,const_wide_int,const_double,const_vector") 56c2b8dc6dSmatt (match_test "op == CONST0_RTX (GET_MODE (op))"))) 57c2b8dc6dSmatt 58c2b8dc6dSmatt(define_predicate "reg_or_0_operand" 59c2b8dc6dSmatt (ior (match_operand 0 "const_0_operand") 60c2b8dc6dSmatt (match_operand 0 "register_operand"))) 61c2b8dc6dSmatt 626a5c9aabSmrg;; Only use branch-on-bit sequences when the mask is not an ANDI immediate. 636a5c9aabSmrg(define_predicate "branch_on_bit_operand" 64c2b8dc6dSmatt (and (match_code "const_int") 656a5c9aabSmrg (match_test "INTVAL (op) >= IMM_BITS - 1"))) 66c2b8dc6dSmatt 67c2b8dc6dSmatt;; A legitimate CONST_INT operand that takes more than one instruction 68c2b8dc6dSmatt;; to load. 69c2b8dc6dSmatt(define_predicate "splittable_const_int_operand" 70c2b8dc6dSmatt (match_code "const_int") 71c2b8dc6dSmatt{ 72c2b8dc6dSmatt /* Don't handle multi-word moves this way; we don't want to introduce 73c2b8dc6dSmatt the individual word-mode moves until after reload. */ 74c2b8dc6dSmatt if (GET_MODE_SIZE (mode) > UNITS_PER_WORD) 75c2b8dc6dSmatt return false; 76c2b8dc6dSmatt 77c2b8dc6dSmatt /* Otherwise check whether the constant can be loaded in a single 78c2b8dc6dSmatt instruction. */ 796a5c9aabSmrg return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); 80c2b8dc6dSmatt}) 81c2b8dc6dSmatt 82ff135a7aSmrg(define_predicate "p2m1_shift_operand" 83ff135a7aSmrg (match_code "const_int") 84ff135a7aSmrg{ 85ff135a7aSmrg int val = exact_log2 (INTVAL (op) + 1); 86ff135a7aSmrg if (val < 12) 87ff135a7aSmrg return false; 88ff135a7aSmrg return true; 89ff135a7aSmrg }) 90ff135a7aSmrg 91ff135a7aSmrg(define_predicate "high_mask_shift_operand" 92ff135a7aSmrg (match_code "const_int") 93ff135a7aSmrg{ 94ff135a7aSmrg int val1 = clz_hwi (~ INTVAL (op)); 95ff135a7aSmrg int val0 = ctz_hwi (INTVAL (op)); 96ff135a7aSmrg if ((val0 + val1 == BITS_PER_WORD) 97ff135a7aSmrg && val0 > 31 && val0 < 64) 98ff135a7aSmrg return true; 99ff135a7aSmrg return false; 100ff135a7aSmrg}) 101ff135a7aSmrg 102c2b8dc6dSmatt(define_predicate "move_operand" 103c2b8dc6dSmatt (match_operand 0 "general_operand") 104c2b8dc6dSmatt{ 105c2b8dc6dSmatt enum riscv_symbol_type symbol_type; 106c2b8dc6dSmatt 107c2b8dc6dSmatt /* The thinking here is as follows: 108c2b8dc6dSmatt 109c2b8dc6dSmatt (1) The move expanders should split complex load sequences into 110c2b8dc6dSmatt individual instructions. Those individual instructions can 111c2b8dc6dSmatt then be optimized by all rtl passes. 112c2b8dc6dSmatt 113c2b8dc6dSmatt (2) The target of pre-reload load sequences should not be used 114c2b8dc6dSmatt to store temporary results. If the target register is only 115c2b8dc6dSmatt assigned one value, reload can rematerialize that value 116c2b8dc6dSmatt on demand, rather than spill it to the stack. 117c2b8dc6dSmatt 118c2b8dc6dSmatt (3) If we allowed pre-reload passes like combine and cse to recreate 119c2b8dc6dSmatt complex load sequences, we would want to be able to split the 120c2b8dc6dSmatt sequences before reload as well, so that the pre-reload scheduler 121c2b8dc6dSmatt can see the individual instructions. This falls foul of (2); 122c2b8dc6dSmatt the splitter would be forced to reuse the target register for 123c2b8dc6dSmatt intermediate results. 124c2b8dc6dSmatt 125c2b8dc6dSmatt (4) We want to define complex load splitters for combine. These 126c2b8dc6dSmatt splitters can request a temporary scratch register, which avoids 127c2b8dc6dSmatt the problem in (2). They allow things like: 128c2b8dc6dSmatt 129c2b8dc6dSmatt (set (reg T1) (high SYM)) 130c2b8dc6dSmatt (set (reg T2) (low (reg T1) SYM)) 131c2b8dc6dSmatt (set (reg X) (plus (reg T2) (const_int OFFSET))) 132c2b8dc6dSmatt 133c2b8dc6dSmatt to be combined into: 134c2b8dc6dSmatt 135c2b8dc6dSmatt (set (reg T3) (high SYM+OFFSET)) 136c2b8dc6dSmatt (set (reg X) (lo_sum (reg T3) SYM+OFFSET)) 137c2b8dc6dSmatt 138c2b8dc6dSmatt if T2 is only used this once. */ 139c2b8dc6dSmatt switch (GET_CODE (op)) 140c2b8dc6dSmatt { 141c2b8dc6dSmatt case CONST_INT: 142c2b8dc6dSmatt return !splittable_const_int_operand (op, mode); 143c2b8dc6dSmatt 144c2b8dc6dSmatt case CONST: 145c2b8dc6dSmatt case SYMBOL_REF: 146c2b8dc6dSmatt case LABEL_REF: 1476a5c9aabSmrg return riscv_symbolic_constant_p (op, &symbol_type) 1486a5c9aabSmrg && !riscv_split_symbol_type (symbol_type); 149c2b8dc6dSmatt 150c2b8dc6dSmatt case HIGH: 151c2b8dc6dSmatt op = XEXP (op, 0); 1526a5c9aabSmrg return riscv_symbolic_constant_p (op, &symbol_type) 1536a5c9aabSmrg && riscv_split_symbol_type (symbol_type) 1546a5c9aabSmrg && symbol_type != SYMBOL_PCREL; 155c2b8dc6dSmatt 156c2b8dc6dSmatt default: 157c2b8dc6dSmatt return true; 158c2b8dc6dSmatt } 159c2b8dc6dSmatt}) 160c2b8dc6dSmatt 161c2b8dc6dSmatt(define_predicate "symbolic_operand" 162c2b8dc6dSmatt (match_code "const,symbol_ref,label_ref") 163c2b8dc6dSmatt{ 164c2b8dc6dSmatt enum riscv_symbol_type type; 165c2b8dc6dSmatt return riscv_symbolic_constant_p (op, &type); 166c2b8dc6dSmatt}) 167c2b8dc6dSmatt 168c2b8dc6dSmatt(define_predicate "absolute_symbolic_operand" 169c2b8dc6dSmatt (match_code "const,symbol_ref,label_ref") 170c2b8dc6dSmatt{ 171c2b8dc6dSmatt enum riscv_symbol_type type; 172c2b8dc6dSmatt return (riscv_symbolic_constant_p (op, &type) 1736a5c9aabSmrg && (type == SYMBOL_ABSOLUTE || type == SYMBOL_PCREL)); 174c2b8dc6dSmatt}) 175c2b8dc6dSmatt 176c2b8dc6dSmatt(define_predicate "plt_symbolic_operand" 177c2b8dc6dSmatt (match_code "const,symbol_ref,label_ref") 178c2b8dc6dSmatt{ 179c2b8dc6dSmatt enum riscv_symbol_type type; 180c2b8dc6dSmatt return (riscv_symbolic_constant_p (op, &type) 181c2b8dc6dSmatt && type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT); 182c2b8dc6dSmatt}) 183c2b8dc6dSmatt 184c2b8dc6dSmatt(define_predicate "call_insn_operand" 185c2b8dc6dSmatt (ior (match_operand 0 "absolute_symbolic_operand") 186c2b8dc6dSmatt (match_operand 0 "plt_symbolic_operand") 187c2b8dc6dSmatt (match_operand 0 "register_operand"))) 188c2b8dc6dSmatt 189c2b8dc6dSmatt(define_predicate "modular_operator" 190c2b8dc6dSmatt (match_code "plus,minus,mult,ashift")) 191c2b8dc6dSmatt 192c2b8dc6dSmatt(define_predicate "equality_operator" 193c2b8dc6dSmatt (match_code "eq,ne")) 194c2b8dc6dSmatt 195c2b8dc6dSmatt(define_predicate "order_operator" 196c2b8dc6dSmatt (match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu")) 197c2b8dc6dSmatt 1986a5c9aabSmrg(define_predicate "signed_order_operator" 1996a5c9aabSmrg (match_code "eq,ne,lt,le,ge,gt")) 2006a5c9aabSmrg 2016a5c9aabSmrg(define_predicate "fp_native_comparison" 202c2b8dc6dSmatt (match_code "eq,lt,le,gt,ge")) 203c2b8dc6dSmatt 2046a5c9aabSmrg(define_predicate "fp_scc_comparison" 2056a5c9aabSmrg (match_code "unordered,ordered,unlt,unge,unle,ungt,ltgt,ne,eq,lt,le,gt,ge")) 2066a5c9aabSmrg 2076a5c9aabSmrg(define_predicate "fp_branch_comparison" 2086a5c9aabSmrg (match_code "unordered,ordered,unlt,unge,unle,ungt,uneq,ltgt,ne,eq,lt,le,gt,ge")) 209*2f055536Smrg 210*2f055536Smrg(define_special_predicate "gpr_save_operation" 211*2f055536Smrg (match_code "parallel") 212*2f055536Smrg{ 213*2f055536Smrg return riscv_gpr_save_operation_p (op); 214*2f055536Smrg}) 215