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