xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/cr16/predicates.md (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1;; Predicates of machine description for CR16.
2;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
3;; Contributed by KPIT Cummins Infosystems Limited.
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
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; 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;;  Predicates
22
23;; Predicates for sbit/cbit instructions
24;; bit operand used for the generation of bit insn generation
25(define_predicate "bit_operand"
26  (match_code "mem")
27{
28  return ((GET_CODE (op) == MEM && OK_FOR_Z (op)));
29})
30
31;; Unsigned 4-bits constant int or double value.
32(define_predicate "u4bits_operand"
33  (match_code "const_int,const_double")
34{
35  if (GET_CODE (op) == CONST_DOUBLE)
36    return cr16_const_double_ok (op);
37    return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 4)) ? 1 : 0;
38})
39
40;; Operand is a constant integer where
41;; only one bit is set to 1.
42(define_predicate "one_bit_operand"
43  (match_code "const_int")
44{
45  unsigned int val;
46
47  val = INTVAL (op);
48  if (mode == QImode)
49    val &= 0xff;
50  else if (mode == HImode)
51    val &= 0xffff;
52  else
53    gcc_unreachable();
54
55  if (val != 0)
56    return (val & (val - 1)) == 0; /* true if only one bit is set.  */
57  else
58    return 0;
59})
60
61;; Operand is a constant integer where
62;; only one bit is set to 0.
63(define_predicate "rev_one_bit_operand"
64  (match_code "const_int")
65{
66  unsigned int val;
67
68  val = ~INTVAL (op); /* Invert and use.  */
69  if (mode == QImode)
70    val &= 0xff;
71  else if (mode == HImode)
72    val &= 0xffff;
73  else
74    gcc_unreachable();
75
76  if (val != 0)
77    return (val & (val - 1)) == 0; /* true if only one bit is set.  */
78  else
79    return 0;
80})
81
82;; Predicates for shift instructions
83;; Immediate operand predicate for count in shift operations.
84;; Immediate shall be 3-bits in case operand to be operated on
85;; is a qi mode operand.
86(define_predicate "shift_qi_imm_operand"
87  (match_code "const_int")
88{
89  return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 3)) ? 1 : 0;
90})
91
92;; Immediate shall be 4-bits in case operand to be operated on
93;; is a hi mode operand.
94(define_predicate "shift_hi_imm_operand"
95  (match_code "const_int")
96{
97  return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 4)) ? 1 : 0;
98})
99
100;; Immediate shall be 3-bits in case operand to be operated on
101;; is a si mode operand.
102(define_predicate "shift_si_imm_operand"
103  (match_code "const_int")
104{
105  return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 5)) ? 1 : 0;
106})
107
108;; Predicates for jump/call instructions
109;; Jump immediate cannot be more than 24-bits
110(define_predicate "jump_imm_operand"
111  (match_code "const_int")
112{
113  return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 24)) ? 1 : 0;
114})
115
116;; Call immediate cannot be more than 24-bits
117(define_predicate "call_imm_operand"
118  (match_operand 0 "immediate_operand")
119{
120  if (GET_CODE (op) != CONST_INT) return 1;
121    return (UNSIGNED_INT_FITS_N_BITS(INTVAL (op), 24)) ? 1 : 0;
122})
123
124;; Operand is register or 4-bit immediate operand
125(define_predicate "reg_or_u4bits_operand"
126  (ior (match_operand 0 "u4bits_operand")
127       (match_operand 0 "register_operand")))
128
129;; Operand is a register or symbol reference
130(define_predicate "reg_or_sym_operand"
131  (ior (match_code "symbol_ref")
132       (match_operand 0 "register_operand")))
133
134;; Operand is a non stack pointer register
135(define_predicate "nosp_reg_operand"
136  (and (match_operand 0 "register_operand")
137       (match_test "REGNO (op) != SP_REGNUM")))
138
139(define_predicate "hard_reg_operand"
140  (and (match_operand 0 "register_operand")
141       (match_test "REGNO (op) <= 15")))
142
143;; Operand is a memory reference and
144;; not a push operand.
145(define_predicate "store_operand"
146  (and (match_operand 0 "memory_operand")
147       (not (match_operand 0 "push_operand"))))
148
149;; Helper predicate
150(define_predicate "reg_or_int_operand"
151  (ior (match_code "const_int")
152       (match_operand 0 "register_operand")))
153
154;;
155;;
156;; Atithmetic/logical predicates
157
158;; QI Helper
159(define_predicate "arith_qi_operand"
160   (match_code "const_int")
161{
162        return (IN_RAN(INTVAL (op), 0, 15) && ((INTVAL (op) != 9)
163                || (INTVAL (op) != 11))) ? 1 : 0 ;
164})
165
166;;QI Reg, subreg(reg) or const_int.
167(define_predicate "reg_qi_int_operand"
168  (ior (match_operand 0 "arith_qi_operand")
169       (match_operand 0 "register_operand")))
170
171;; HI Helper
172(define_predicate "arith_hi_operand"
173   (match_code "const_int")
174{
175        return (IN_RAN(INTVAL (op), -32768, 32768) ) ? 1 : 0 ;
176})
177
178;;HI Reg, subreg(reg) or const_int.
179(define_predicate "reg_hi_int_operand"
180  (ior (match_operand 0 "arith_hi_operand")
181       (match_operand 0 "register_operand")))
182
183;;SI Reg, subreg(reg) or const_int.
184(define_predicate "reg_si_int_operand"
185  (ior (match_operand 0 "const_int_operand")
186       (match_operand 0 "register_operand")))
187
188;;
189;; Shift predicates
190
191;; QI Helper
192(define_predicate "shift_qi_operand"
193   (match_code "const_int")
194{
195        return (IN_RAN(INTVAL (op), 0, 7) ) ? 1 : 0;
196})
197
198;;QI Reg, subreg(reg) or const_int.
199(define_predicate "shift_reg_qi_int_operand"
200  (ior (match_operand 0 "shift_qi_operand")
201       (match_operand 0 "register_operand")))
202
203;; HI Helper
204(define_predicate "shift_hi_operand"
205   (match_code "const_int")
206{
207        return (IN_RAN(INTVAL (op), 0, 15) ) ? 1 : 0 ;
208})
209
210;;HI Reg, subreg(reg) or const_int.
211(define_predicate "shift_reg_hi_int_operand"
212  (ior (match_operand 0 "shift_hi_operand")
213       (match_operand 0 "register_operand")))
214
215;; SI Helper
216(define_predicate "shift_si_operand"
217   (match_code "const_int")
218{
219        return (IN_RAN(INTVAL (op), 0, 31) ) ? 1 : 0;
220})
221
222;;SI Reg, subreg(reg) or const_int.
223(define_predicate "shift_reg_si_int_operand"
224  (ior (match_operand 0 "shift_si_operand")
225       (match_operand 0 "register_operand")))
226