]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/pru/alu-zext.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / pru / alu-zext.md
1 ;; ALU operations with zero extensions
2 ;;
3 ;; Copyright (C) 2015-2024 Free Software Foundation, Inc.
4 ;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ; All PRU ALU instructions automatically zero-extend their source operands,
23 ; and zero-extract the result into the destination register. This is
24 ; described in the machine description by defining a separate pattern
25 ; for each possible combination of zero_extend and mode for input operands.
26 ;
27 ; An unfortunate side effect is that quite a few invalid RTL patterns are
28 ; generated. For example:
29 ; ... (zero_extend:SI (match_operand:SI ...)) ...
30 ; These patterns are harmless since no pass should generate such RTL. This
31 ; shortcut allows us to keep small and concise machine description patterns.
32
33
34 (define_subst_attr "alu2_zext" "alu2_zext_subst" "_z" "_noz")
35
36 (define_subst_attr "alu3_zext_op1" "alu3_zext_op1_subst" "_z1" "_noz1")
37 (define_subst_attr "alu3_zext_op2" "alu3_zext_op2_subst" "_z2" "_noz2")
38 (define_subst_attr "alu3_zext" "alu3_zext_subst" "_z" "_noz")
39
40 (define_subst_attr "lmbd_zext_op1" "lmbd_zext_op1_subst" "_z1" "_noz1")
41 (define_subst_attr "lmbd_zext_op2" "lmbd_zext_op2_subst" "_z2" "_noz2")
42 (define_subst_attr "lmbd_zext" "lmbd_zext_subst" "_z" "_noz")
43
44 (define_subst_attr "bitalu_zext" "bitalu_zext_subst" "_z" "_noz")
45
46 (define_code_iterator ALUOP3 [plus minus and ior xor umin umax ashift lshiftrt])
47 (define_code_iterator ALUOP2 [neg not])
48
49 ;; Arithmetic Operations
50
51 (define_insn "add_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
52 [(set (match_operand:EQD 0 "register_operand" "=r,r,r")
53 (plus:EQD
54 (zero_extend:EQD
55 (match_operand:EQS0 1 "register_operand" "%r,r,r"))
56 (zero_extend:EQD
57 (match_operand:EQS1 2 "nonmemory_operand" "r,<EQS1:ubyte_constr>,M"))))]
58 ""
59 "@
60 add\\t%0, %1, %2
61 add\\t%0, %1, %u2
62 sub\\t%0, %1, %n2"
63 [(set_attr "type" "alu")])
64
65 (define_insn "sub_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
66 [(set (match_operand:EQD 0 "register_operand" "=r,r")
67 (minus:EQD
68 (zero_extend:EQD
69 (match_operand:EQS0 1 "reg_or_ubyte_operand" "r,<EQS0:ubyte_constr>"))
70 (zero_extend:EQD
71 (match_operand:EQS1 2 "register_operand" "r,r"))))]
72 ""
73 "@
74 sub\\t%0, %1, %2
75 rsb\\t%0, %2, %u1"
76 [(set_attr "type" "alu")])
77
78
79 ;; Left Most Bit Detect instruction.
80 (define_insn "pru_lmbd_impl<EQD:mode><EQS0:mode><EQS1:mode>_<lmbd_zext><lmbd_zext_op1><lmbd_zext_op2>"
81 [(set (match_operand:EQD 0 "register_operand" "=r")
82 (unspec:EQD
83 [(zero_extend:EQD
84 (match_operand:EQS0 1 "register_operand" "r"))
85 (zero_extend:EQD
86 (match_operand:EQS1 2 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))]
87 UNSPEC_LMBD))]
88 ""
89 "lmbd\t%0, %1, %2"
90 [(set_attr "type" "alu")])
91
92 (define_insn "neg_impl<EQD:mode><EQS0:mode>_<alu2_zext>"
93 [(set (match_operand:EQD 0 "register_operand" "=r")
94 (neg:EQD
95 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))))]
96 ""
97 "rsb\\t%0, %1, 0"
98 [(set_attr "type" "alu")])
99
100
101 (define_insn "one_cmpl_impl<EQD:mode><EQS0:mode>_<alu2_zext>"
102 [(set (match_operand:EQD 0 "register_operand" "=r")
103 (not:EQD
104 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))))]
105 ""
106 "not\\t%0, %1"
107 [(set_attr "type" "alu")])
108
109 ; Specialized IOR/AND patterns for matching setbit/clearbit instructions.
110 ;
111 ; TODO - allow clrbit and setbit to support (1 << REG) constructs
112
113 (define_insn "clearbit_<EQD:mode><EQS0:mode>_<bitalu_zext>"
114 [(set (match_operand:EQD 0 "register_operand" "=r")
115 (and:EQD
116 (zero_extend:EQD
117 (match_operand:EQS0 1 "register_operand" "r"))
118 (match_operand:EQD 2 "single_zero_operand" "n")))]
119 ""
120 "clr\\t%0, %1, %V2"
121 [(set_attr "type" "alu")])
122
123 (define_insn "setbit_<EQD:mode><EQS0:mode>_<bitalu_zext>"
124 [(set (match_operand:EQD 0 "register_operand" "=r")
125 (ior:EQD
126 (zero_extend:EQD
127 (match_operand:EQS0 1 "register_operand" "r"))
128 (match_operand:EQD 2 "single_one_operand" "n")))]
129 ""
130 "set\\t%0, %1, %T2"
131 [(set_attr "type" "alu")])
132
133 ; Regular ALU ops
134 (define_insn "<code>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
135 [(set (match_operand:EQD 0 "register_operand" "=r")
136 (LOGICAL:EQD
137 (zero_extend:EQD
138 (match_operand:EQS0 1 "register_operand" "%r"))
139 (zero_extend:EQD
140 (match_operand:EQS1 2 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))))]
141 ""
142 "<logical_asm>\\t%0, %1, %u2"
143 [(set_attr "type" "alu")])
144
145 ; Shift ALU ops
146 (define_insn "<shift_op>_impl<EQD:mode><EQS0:mode><EQS1:mode>_<alu3_zext><alu3_zext_op1><alu3_zext_op2>"
147 [(set (match_operand:EQD 0 "register_operand" "=r")
148 (SHIFT:EQD
149 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))
150 (zero_extend:EQD (match_operand:EQS1 2 "shift_operand" "rL"))))]
151 ""
152 "<shift_asm>\\t%0, %1, %2"
153 [(set_attr "type" "alu")])
154
155 ;; Substitutions
156
157 (define_subst "alu2_zext_subst"
158 [(set (match_operand:EQD 0)
159 (ALUOP2:EQD (zero_extend:EQD (match_operand:EQD 1))))]
160 ""
161 [(set (match_dup 0)
162 (ALUOP2:EQD (match_dup 1)))])
163
164 (define_subst "bitalu_zext_subst"
165 [(set (match_operand:EQD 0)
166 (ALUOP3:EQD (zero_extend:EQD (match_operand:EQD 1))
167 (match_operand:EQD 2)))]
168 ""
169 [(set (match_dup 0)
170 (ALUOP3:EQD (match_dup 1)
171 (match_dup 2)))])
172
173 (define_subst "alu3_zext_subst"
174 [(set (match_operand:EQD 0)
175 (ALUOP3:EQD (zero_extend:EQD (match_operand:EQD 1))
176 (zero_extend:EQD (match_operand:EQD 2))))]
177 ""
178 [(set (match_dup 0)
179 (ALUOP3:EQD (match_dup 1)
180 (match_dup 2)))])
181
182 (define_subst "alu3_zext_op1_subst"
183 [(set (match_operand:EQD 0)
184 (ALUOP3:EQD (zero_extend:EQD (match_operand:EQD 1))
185 (zero_extend:EQD (match_operand:EQS1 2))))]
186 ""
187 [(set (match_dup 0)
188 (ALUOP3:EQD (match_dup 1)
189 (zero_extend:EQD (match_dup 2))))])
190
191 (define_subst "alu3_zext_op2_subst"
192 [(set (match_operand:EQD 0)
193 (ALUOP3:EQD (zero_extend:EQD (match_operand:EQS0 1))
194 (zero_extend:EQD (match_operand:EQD 2))))]
195 ""
196 [(set (match_dup 0)
197 (ALUOP3:EQD (zero_extend:EQD (match_dup 1))
198 (match_dup 2)))])
199
200
201 (define_subst "lmbd_zext_subst"
202 [(set (match_operand:EQD 0)
203 (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
204 (zero_extend:EQD (match_operand:EQD 2))]
205 UNSPEC_LMBD))]
206 ""
207 [(set (match_dup 0)
208 (unspec:EQD [(match_dup 1)
209 (match_dup 2)]
210 UNSPEC_LMBD))])
211
212 (define_subst "lmbd_zext_op1_subst"
213 [(set (match_operand:EQD 0)
214 (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
215 (zero_extend:EQD (match_operand:EQS1 2))]
216 UNSPEC_LMBD))]
217 ""
218 [(set (match_dup 0)
219 (unspec:EQD [(match_dup 1)
220 (zero_extend:EQD (match_dup 2))]
221 UNSPEC_LMBD))])
222
223 (define_subst "lmbd_zext_op2_subst"
224 [(set (match_operand:EQD 0)
225 (unspec:EQD [(zero_extend:EQD (match_operand:EQD 1))
226 (zero_extend:EQD (match_operand:EQD 2))]
227 UNSPEC_LMBD))]
228 ""
229 [(set (match_dup 0)
230 (unspec:EQD [(zero_extend:EQD (match_dup 1))
231 (match_dup 2)]
232 UNSPEC_LMBD))])