Skip analyzer strndup test on hppa*-*-hpux*
[official-gcc.git] / gcc / config / pru / alu-zext.md
blob69d66d8f6f9bdc0101690e6ad7ea2196b5b916ed
1 ;; ALU operations with zero extensions
2 ;;
3 ;; Copyright (C) 2015-2023 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.
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")
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")])
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")])
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")])
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")])
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")])
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")
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")])
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")])
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")])
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")])
155 ;; Substitutions
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)))])
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)))])
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)))])
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))))])
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)))])
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))])
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))])
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))])