xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/m32c/muldiv.md (revision 70f7362772ba52b749c976fb5e86e39a8b2c9afc)
1;; Machine Descriptions for R8C/M16C/M32C
2;; Copyright (C) 2005-2020 Free Software Foundation, Inc.
3;; Contributed by Red Hat.
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;; multiply and divide
22
23; Here is the pattern for the const_int.
24(define_insn "mulqihi3_c"
25  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
26        (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0"))
27                 (match_operand 2 "immediate_operand" "i,i")))]
28  ""
29  "mul.b\t%2,%1"
30  [(set_attr "flags" "o")]
31)
32
33; Here is the pattern for registers and such.
34(define_insn "mulqihi3_r"
35  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
36        (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
37                 (sign_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))]
38  ""
39  "mul.b\t%2,%1"
40  [(set_attr "flags" "o")]
41)
42
43; Don't try to sign_extend a const_int.  Same for all other multiplies.
44(define_expand "mulqihi3"
45  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
46        (mult:HI (sign_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
47                 (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))]
48  ""
49  "{ if (GET_MODE (operands[2]) != VOIDmode)
50      operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]); }"
51)
52
53(define_insn "umulqihi3_c"
54  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm")
55        (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0"))
56                 (match_operand 2 "immediate_operand" "i,i")))]
57  ""
58  "mulu.b\t%U2,%1"
59  [(set_attr "flags" "o")]
60)
61
62(define_insn "umulqihi3_r"
63  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
64        (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
65                 (zero_extend:HI (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm"))))]
66  ""
67  "mulu.b\t%U2,%1"
68  [(set_attr "flags" "o")]
69)
70
71(define_expand "umulqihi3"
72  [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm,Raa,Raa")
73        (mult:HI (zero_extend:HI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0"))
74                 (match_operand:QI 2 "mra_operand" "RqiSd,?Rmm,RqiSd,?Rmm,RhlSd,?Rmm")))]
75  ""
76  "{ if (GET_MODE (operands[2]) != VOIDmode)
77      operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]); }"
78)
79
80(define_insn "mulhisi3_c"
81  [(set (match_operand:SI 0 "ra_operand" "=Rsi")
82        (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0"))
83                 (match_operand:HI 2 "immediate_operand" "i")))]
84  ""
85  "mul.w\t%2,%1"
86  [(set_attr "flags" "o")]
87)
88
89(define_insn "mulhisi3_r"
90  [(set (match_operand:SI 0 "mra_operand" "=Rsi,Rsi")
91        (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0"))
92                 (sign_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm"))))]
93  ""
94  "mul.w\t%2,%1"
95  [(set_attr "flags" "o")]
96)
97
98(define_expand "mulhisi3"
99  [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
100        (mult:SI (sign_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
101                 (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))]
102  ""
103  "{ if (GET_MODE (operands[2]) != VOIDmode)
104      operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]); }"
105)
106
107(define_insn "umulhisi3_c"
108  [(set (match_operand:SI 0 "ra_operand" "=Rsi")
109        (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0"))
110                 (match_operand 2 "immediate_operand" "i")))]
111  ""
112  "mulu.w\t%u2,%1"
113  [(set_attr "flags" "o")]
114)
115
116(define_insn "umulhisi3_r"
117  [(set (match_operand:SI 0 "mra_operand" "=Rsi,Rsi")
118        (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0"))
119                 (zero_extend:SI (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm"))))]
120  ""
121  "mulu.w\t%u2,%1"
122  [(set_attr "flags" "o")]
123)
124
125(define_expand "umulhisi3"
126  [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm")
127        (mult:SI (zero_extend:SI (match_operand:HI 1 "mra_operand" "%0,0,0,0"))
128                 (match_operand:HI 2 "mra_operand" "RhiSd,?Rmm,RhiSd,?Rmm")))]
129  ""
130  "{ if (GET_MODE (operands[2]) != VOIDmode)
131      operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); }"
132)
133
134
135; GCC expects to be able to multiply pointer-sized integers too, but
136; fortunately it only multiplies by powers of two, although sometimes
137; they're negative.
138(define_insn "mulpsi3_op"
139  [(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
140	(mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
141		  (match_operand 2 "m32c_psi_scale" "Ilb")))]
142  "TARGET_A24"
143  "shl.l\t%b2,%0"
144  [(set_attr "flags" "szc")]
145  )
146
147(define_expand "mulpsi3"
148  [(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
149	(mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
150		  (match_operand 2 "m32c_psi_scale" "Ilb")))]
151  "TARGET_A24"
152  "if (GET_CODE (operands[2]) != CONST_INT
153       || ! m32c_psi_scale (operands[2], PSImode))
154     {
155       m32c_expand_neg_mulpsi3 (operands);
156       DONE;
157     }"
158  )
159
160(define_insn "mulsi3"
161  [(set (match_operand:SI 0 "r0123_operand" "=R02,R02")
162        (mult:SI (match_operand:SI 1 "r0123_operand" "%0,0")
163                 (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))]
164  "TARGET_M32C"
165  "mul.l\t%2,%1"
166  [(set_attr "flags" "o")]
167)
168
169(define_expand "divmodqi4"
170  [(set (match_dup 4)
171	(sign_extend:HI (match_operand:QI 1 "register_operand" "0,0")))
172   (parallel [(set (match_operand:QI 0 "register_operand" "=R0w,R0w")
173		   (div:QI (match_dup 4)
174			   (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
175	      (set (match_operand:QI 3 "register_operand" "=&R0h,&R0h")
176		   (mod:QI (match_dup 4) (match_dup 2)))
177	      ])]
178  "0"
179  "operands[4] = gen_reg_rtx (HImode);"
180  )
181
182(define_insn "divmodqi4_n"
183  [(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
184	(div:QI (match_operand:HI 1 "register_operand" "R0w,R0w")
185		(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
186   (set (match_operand:QI 3 "register_operand" "=R0h,R0h")
187	(mod:QI (match_dup 1) (match_dup 2)))
188   ]
189  "0"
190  "div.b\t%2"
191  [(set_attr "flags" "o")]
192  )
193
194(define_expand "udivmodqi4"
195  [(set (match_dup 4)
196	(zero_extend:HI (match_operand:QI 1 "register_operand" "0,0")))
197   (parallel [(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
198		   (udiv:QI (match_dup 4)
199			   (match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
200	      (set (match_operand:QI 3 "register_operand" "=&R0h,&R0h")
201		   (umod:QI (match_dup 4) (match_dup 2)))
202	      ])]
203  "0"
204  "operands[4] = gen_reg_rtx (HImode);"
205  )
206
207(define_insn "udivmodqi4_n"
208  [(set (match_operand:QI 0 "register_operand" "=R0l,R0l")
209	(udiv:QI (match_operand:HI 1 "register_operand" "R0w,R0w")
210		(match_operand:QI 2 "general_operand" "iRqiSd,?Rmm")))
211   (set (match_operand:QI 3 "register_operand" "=R0h,R0h")
212	(umod:QI (match_dup 1) (match_dup 2)))
213   ]
214  "0"
215  "divu.b\t%2"
216  [(set_attr "flags" "o")]
217  )
218
219(define_expand "divmodhi4"
220  [(set (match_dup 4)
221	(sign_extend:SI (match_operand:HI 1 "register_operand" "0,0")))
222   (parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w")
223		   (div:HI (match_dup 4)
224			   (match_operand:HI 2 "general_operand" "iRhiSd,?Rmm")))
225	      (set (match_operand:HI 3 "register_operand" "=R2w,R2w")
226		   (mod:HI (match_dup 4) (match_dup 2)))
227	      ])]
228  ""
229  "operands[4] = gen_reg_rtx (SImode);"
230  )
231
232(define_insn "divmodhi4_n"
233  [(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w")
234	(div:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02")
235		(match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm")))
236   (set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w")
237	(mod:HI (match_dup 1) (match_dup 2)))
238   ]
239  ""
240  "div.w\t%2"
241  [(set_attr "flags" "o")]
242  )
243
244(define_expand "udivmodhi4"
245  [(set (match_dup 4)
246	(zero_extend:SI (match_operand:HI 1 "register_operand" "0,0")))
247   (parallel [(set (match_operand:HI 0 "register_operand" "=R0w,R0w")
248		   (udiv:HI (match_dup 4)
249			   (match_operand:HI 2 "general_operand" "iRhiSd,?Rmm")))
250	      (set (match_operand:HI 3 "register_operand" "=R2w,R2w")
251		   (umod:HI (match_dup 4) (match_dup 2)))
252	      ])]
253  ""
254  "operands[4] = gen_reg_rtx (SImode);"
255  )
256
257(define_insn "udivmodhi4_n"
258  [(set (match_operand:HI 0 "m32c_r0_operand" "=R0w,R0w")
259	(udiv:HI (match_operand:SI 1 "m32c_r0_operand" "R02,R02")
260		(match_operand:HI 2 "m32c_notr2_operand" "iR1wR3wRaaSd,?Rmm")))
261   (set (match_operand:HI 3 "m32c_r2_operand" "=R2w,R2w")
262	(umod:HI (match_dup 1) (match_dup 2)))
263   ]
264  ""
265  "divu.w\t%2"
266  [(set_attr "flags" "o")]
267  )
268
269(define_insn "divsi3"
270  [(set (match_operand:SI 0 "r0123_operand" "=R02,R02")
271        (div:SI (match_operand:SI 1 "r0123_operand" "0,0")
272                (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))]
273  "TARGET_M32C"
274  "div.l\t%2"
275  [(set_attr "flags" "o")]
276)
277
278(define_insn "udivsi3"
279  [(set (match_operand:SI 0 "r0123_operand" "=R02,R02")
280        (udiv:SI (match_operand:SI 1 "r0123_operand" "0,0")
281                 (match_operand:SI 2 "mra_operand" "RsiSd,?Rmm")))]
282  "TARGET_M32C"
283  "divu.l\t%2"
284  [(set_attr "flags" "o")]
285)
286
287
288