1 ;; ALU operations with zero extensions
3 ;; Copyright (C) 2015-2023 Free Software Foundation, Inc.
4 ;; Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
6 ;; This file is part of GCC.
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)
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.
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/>.
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.
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.
34 (define_subst_attr "alu2_zext" "alu2_zext_subst" "_z" "_noz")
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")
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")
44 (define_subst_attr "bitalu_zext" "bitalu_zext_subst" "_z" "_noz")
46 (define_code_iterator ALUOP3 [plus minus and ior xor umin umax ashift lshiftrt])
47 (define_code_iterator ALUOP2 [neg not])
49 ;; Arithmetic Operations
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")
55 (match_operand:EQS0 1 "register_operand" "%r,r,r"))
57 (match_operand:EQS1 2 "nonmemory_operand" "r,<EQS1:ubyte_constr>,M"))))]
63 [(set_attr "type" "alu")])
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")
69 (match_operand:EQS0 1 "reg_or_ubyte_operand" "r,<EQS0:ubyte_constr>"))
71 (match_operand:EQS1 2 "register_operand" "r,r"))))]
76 [(set_attr "type" "alu")])
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")
84 (match_operand:EQS0 1 "register_operand" "r"))
86 (match_operand:EQS1 2 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))]
90 [(set_attr "type" "alu")])
92 (define_insn "neg_impl<EQD:mode><EQS0:mode>_<alu2_zext>"
93 [(set (match_operand:EQD 0 "register_operand" "=r")
95 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))))]
98 [(set_attr "type" "alu")])
101 (define_insn "one_cmpl_impl<EQD:mode><EQS0:mode>_<alu2_zext>"
102 [(set (match_operand:EQD 0 "register_operand" "=r")
104 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))))]
107 [(set_attr "type" "alu")])
109 ; Specialized IOR/AND patterns for matching setbit/clearbit instructions.
111 ; TODO - allow clrbit and setbit to support (1 << REG) constructs
113 (define_insn "clearbit_<EQD:mode><EQS0:mode>_<bitalu_zext>"
114 [(set (match_operand:EQD 0 "register_operand" "=r")
117 (match_operand:EQS0 1 "register_operand" "r"))
118 (match_operand:EQD 2 "single_zero_operand" "n")))]
121 [(set_attr "type" "alu")])
123 (define_insn "setbit_<EQD:mode><EQS0:mode>_<bitalu_zext>"
124 [(set (match_operand:EQD 0 "register_operand" "=r")
127 (match_operand:EQS0 1 "register_operand" "r"))
128 (match_operand:EQD 2 "single_one_operand" "n")))]
131 [(set_attr "type" "alu")])
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")
138 (match_operand:EQS0 1 "register_operand" "%r"))
140 (match_operand:EQS1 2 "reg_or_ubyte_operand" "r<EQS1:ubyte_constr>"))))]
142 "<logical_asm>\\t%0, %1, %u2"
143 [(set_attr "type" "alu")])
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")
149 (zero_extend:EQD (match_operand:EQS0 1 "register_operand" "r"))
150 (zero_extend:EQD (match_operand:EQS1 2 "shift_operand" "rL"))))]
152 "<shift_asm>\\t%0, %1, %2"
153 [(set_attr "type" "alu")])
157 (define_subst "alu2_zext_subst"
158 [(set (match_operand:EQD 0)
159 (ALUOP2:EQD (zero_extend:EQD (match_operand:EQD 1))))]
162 (ALUOP2:EQD (match_dup 1)))])
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)))]
170 (ALUOP3:EQD (match_dup 1)
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))))]
179 (ALUOP3:EQD (match_dup 1)
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))))]
188 (ALUOP3:EQD (match_dup 1)
189 (zero_extend:EQD (match_dup 2))))])
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))))]
197 (ALUOP3:EQD (zero_extend:EQD (match_dup 1))
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))]
208 (unspec:EQD [(match_dup 1)
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))]
219 (unspec:EQD [(match_dup 1)
220 (zero_extend:EQD (match_dup 2))]
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))]
230 (unspec:EQD [(zero_extend:EQD (match_dup 1))