]> gcc.gnu.org Git - gcc.git/blob - gcc/config/avr/avr-fixed.md
bfbdaecf2157aaed1f24e38ae9397bb14ffad17f
[gcc.git] / gcc / config / avr / avr-fixed.md
1 ;; This file contains instructions that support fixed-point operations
2 ;; for Atmel AVR micro controllers.
3 ;; Copyright (C) 2012
4 ;; Free Software Foundation, Inc.
5 ;;
6 ;; Contributed by Sean D'Epagnier (sean@depagnier.com)
7 ;; Georg-Johann Lay (avr@gjlay.de)
8
9 ;; This file is part of GCC.
10 ;;
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15 ;;
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3. If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 (define_mode_iterator ALL1Q [(QQ "") (UQQ "")])
26 (define_mode_iterator ALL2Q [(HQ "") (UHQ "")])
27 (define_mode_iterator ALL2A [(HA "") (UHA "")])
28 (define_mode_iterator ALL2QA [(HQ "") (UHQ "")
29 (HA "") (UHA "")])
30 (define_mode_iterator ALL4A [(SA "") (USA "")])
31
32 ;;; Conversions
33
34 (define_mode_iterator FIXED_A
35 [(QQ "") (UQQ "")
36 (HQ "") (UHQ "") (HA "") (UHA "")
37 (SQ "") (USQ "") (SA "") (USA "")
38 (DQ "") (UDQ "") (DA "") (UDA "")
39 (TA "") (UTA "")
40 (QI "") (HI "") (SI "") (DI "")])
41
42 ;; Same so that be can build cross products
43
44 (define_mode_iterator FIXED_B
45 [(QQ "") (UQQ "")
46 (HQ "") (UHQ "") (HA "") (UHA "")
47 (SQ "") (USQ "") (SA "") (USA "")
48 (DQ "") (UDQ "") (DA "") (UDA "")
49 (TA "") (UTA "")
50 (QI "") (HI "") (SI "") (DI "")])
51
52 (define_insn "fract<FIXED_B:mode><FIXED_A:mode>2"
53 [(set (match_operand:FIXED_A 0 "register_operand" "=r")
54 (fract_convert:FIXED_A
55 (match_operand:FIXED_B 1 "register_operand" "r")))]
56 "<FIXED_B:MODE>mode != <FIXED_A:MODE>mode"
57 {
58 return avr_out_fract (insn, operands, true, NULL);
59 }
60 [(set_attr "cc" "clobber")
61 (set_attr "adjust_len" "sfract")])
62
63 (define_insn "fractuns<FIXED_B:mode><FIXED_A:mode>2"
64 [(set (match_operand:FIXED_A 0 "register_operand" "=r")
65 (unsigned_fract_convert:FIXED_A
66 (match_operand:FIXED_B 1 "register_operand" "r")))]
67 "<FIXED_B:MODE>mode != <FIXED_A:MODE>mode"
68 {
69 return avr_out_fract (insn, operands, false, NULL);
70 }
71 [(set_attr "cc" "clobber")
72 (set_attr "adjust_len" "ufract")])
73
74 ;******************************************************************************
75 ; mul
76
77 ;; "mulqq3" "muluqq3"
78 (define_expand "mul<mode>3"
79 [(parallel [(match_operand:ALL1Q 0 "register_operand" "")
80 (match_operand:ALL1Q 1 "register_operand" "")
81 (match_operand:ALL1Q 2 "register_operand" "")])]
82 ""
83 {
84 emit_insn (AVR_HAVE_MUL
85 ? gen_mul<mode>3_enh (operands[0], operands[1], operands[2])
86 : gen_mul<mode>3_nomul (operands[0], operands[1], operands[2]));
87 DONE;
88 })
89
90 (define_insn "mulqq3_enh"
91 [(set (match_operand:QQ 0 "register_operand" "=r")
92 (mult:QQ (match_operand:QQ 1 "register_operand" "a")
93 (match_operand:QQ 2 "register_operand" "a")))]
94 "AVR_HAVE_MUL"
95 "fmuls %1,%2\;dec r1\;brvs 0f\;inc r1\;0:\;mov %0,r1\;clr __zero_reg__"
96 [(set_attr "length" "6")
97 (set_attr "cc" "clobber")])
98
99 (define_insn "muluqq3_enh"
100 [(set (match_operand:UQQ 0 "register_operand" "=r")
101 (mult:UQQ (match_operand:UQQ 1 "register_operand" "r")
102 (match_operand:UQQ 2 "register_operand" "r")))]
103 "AVR_HAVE_MUL"
104 "mul %1,%2\;mov %0,r1\;clr __zero_reg__"
105 [(set_attr "length" "3")
106 (set_attr "cc" "clobber")])
107
108 (define_expand "mulqq3_nomul"
109 [(set (reg:QQ 24)
110 (match_operand:QQ 1 "register_operand" ""))
111 (set (reg:QQ 25)
112 (match_operand:QQ 2 "register_operand" ""))
113 ;; "*mulqq3.call"
114 (parallel [(set (reg:QQ 23)
115 (mult:QQ (reg:QQ 24)
116 (reg:QQ 25)))
117 (clobber (reg:QI 22))
118 (clobber (reg:HI 24))])
119 (set (match_operand:QQ 0 "register_operand" "")
120 (reg:QQ 23))]
121 "!AVR_HAVE_MUL")
122
123 (define_expand "muluqq3_nomul"
124 [(set (reg:UQQ 22)
125 (match_operand:UQQ 1 "register_operand" ""))
126 (set (reg:UQQ 24)
127 (match_operand:UQQ 2 "register_operand" ""))
128 ;; "*umulqihi3.call"
129 (parallel [(set (reg:HI 24)
130 (mult:HI (zero_extend:HI (reg:QI 22))
131 (zero_extend:HI (reg:QI 24))))
132 (clobber (reg:QI 21))
133 (clobber (reg:HI 22))])
134 (set (match_operand:UQQ 0 "register_operand" "")
135 (reg:UQQ 25))]
136 "!AVR_HAVE_MUL")
137
138 (define_insn "*mulqq3.call"
139 [(set (reg:QQ 23)
140 (mult:QQ (reg:QQ 24)
141 (reg:QQ 25)))
142 (clobber (reg:QI 22))
143 (clobber (reg:HI 24))]
144 "!AVR_HAVE_MUL"
145 "%~call __mulqq3"
146 [(set_attr "type" "xcall")
147 (set_attr "cc" "clobber")])
148
149
150 ;; "mulhq3" "muluhq3"
151 ;; "mulha3" "muluha3"
152 (define_expand "mul<mode>3"
153 [(set (reg:ALL2QA 18)
154 (match_operand:ALL2QA 1 "register_operand" ""))
155 (set (reg:ALL2QA 26)
156 (match_operand:ALL2QA 2 "register_operand" ""))
157 ;; "*mulhq3.call.enh"
158 (parallel [(set (reg:ALL2QA 24)
159 (mult:ALL2QA (reg:ALL2QA 18)
160 (reg:ALL2QA 26)))
161 (clobber (reg:HI 22))])
162 (set (match_operand:ALL2QA 0 "register_operand" "")
163 (reg:ALL2QA 24))]
164 "AVR_HAVE_MUL")
165
166 ;; "*mulhq3.call" "*muluhq3.call"
167 ;; "*mulha3.call" "*muluha3.call"
168 (define_insn "*mul<mode>3.call"
169 [(set (reg:ALL2QA 24)
170 (mult:ALL2QA (reg:ALL2QA 18)
171 (reg:ALL2QA 26)))
172 (clobber (reg:HI 22))]
173 "AVR_HAVE_MUL"
174 "%~call __mul<mode>3"
175 [(set_attr "type" "xcall")
176 (set_attr "cc" "clobber")])
177
178
179 ;; On the enhanced core, don't clobber either input and use a separate output
180
181 ;; "mulsa3" "mulusa3"
182 (define_expand "mul<mode>3"
183 [(set (reg:ALL4A 16)
184 (match_operand:ALL4A 1 "register_operand" ""))
185 (set (reg:ALL4A 20)
186 (match_operand:ALL4A 2 "register_operand" ""))
187 (set (reg:ALL4A 24)
188 (mult:ALL4A (reg:ALL4A 16)
189 (reg:ALL4A 20)))
190 (set (match_operand:ALL4A 0 "register_operand" "")
191 (reg:ALL4A 24))]
192 "AVR_HAVE_MUL")
193
194 ;; "*mulsa3.call" "*mulusa3.call"
195 (define_insn "*mul<mode>3.call"
196 [(set (reg:ALL4A 24)
197 (mult:ALL4A (reg:ALL4A 16)
198 (reg:ALL4A 20)))]
199 "AVR_HAVE_MUL"
200 "%~call __mul<mode>3"
201 [(set_attr "type" "xcall")
202 (set_attr "cc" "clobber")])
203
204 ; / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
205 ; div
206
207 (define_code_iterator usdiv [udiv div])
208
209 ;; "divqq3" "udivuqq3"
210 (define_expand "<code><mode>3"
211 [(set (reg:ALL1Q 25)
212 (match_operand:ALL1Q 1 "register_operand" ""))
213 (set (reg:ALL1Q 22)
214 (match_operand:ALL1Q 2 "register_operand" ""))
215 (parallel [(set (reg:ALL1Q 24)
216 (usdiv:ALL1Q (reg:ALL1Q 25)
217 (reg:ALL1Q 22)))
218 (clobber (reg:QI 25))])
219 (set (match_operand:ALL1Q 0 "register_operand" "")
220 (reg:ALL1Q 24))])
221
222 ;; "*divqq3.call" "*udivuqq3.call"
223 (define_insn "*<code><mode>3.call"
224 [(set (reg:ALL1Q 24)
225 (usdiv:ALL1Q (reg:ALL1Q 25)
226 (reg:ALL1Q 22)))
227 (clobber (reg:QI 25))]
228 ""
229 "%~call __<code><mode>3"
230 [(set_attr "type" "xcall")
231 (set_attr "cc" "clobber")])
232
233 ;; "divhq3" "udivuhq3"
234 ;; "divha3" "udivuha3"
235 (define_expand "<code><mode>3"
236 [(set (reg:ALL2QA 26)
237 (match_operand:ALL2QA 1 "register_operand" ""))
238 (set (reg:ALL2QA 22)
239 (match_operand:ALL2QA 2 "register_operand" ""))
240 (parallel [(set (reg:ALL2QA 24)
241 (usdiv:ALL2QA (reg:ALL2QA 26)
242 (reg:ALL2QA 22)))
243 (clobber (reg:HI 26))
244 (clobber (reg:QI 21))])
245 (set (match_operand:ALL2QA 0 "register_operand" "")
246 (reg:ALL2QA 24))])
247
248 ;; "*divhq3.call" "*udivuhq3.call"
249 ;; "*divha3.call" "*udivuha3.call"
250 (define_insn "*<code><mode>3.call"
251 [(set (reg:ALL2QA 24)
252 (usdiv:ALL2QA (reg:ALL2QA 26)
253 (reg:ALL2QA 22)))
254 (clobber (reg:HI 26))
255 (clobber (reg:QI 21))]
256 ""
257 "%~call __<code><mode>3"
258 [(set_attr "type" "xcall")
259 (set_attr "cc" "clobber")])
260
261 ;; Note the first parameter gets passed in already offset by 2 bytes
262
263 ;; "divsa3" "udivusa3"
264 (define_expand "<code><mode>3"
265 [(set (reg:ALL4A 24)
266 (match_operand:ALL4A 1 "register_operand" ""))
267 (set (reg:ALL4A 18)
268 (match_operand:ALL4A 2 "register_operand" ""))
269 (parallel [(set (reg:ALL4A 22)
270 (usdiv:ALL4A (reg:ALL4A 24)
271 (reg:ALL4A 18)))
272 (clobber (reg:HI 26))
273 (clobber (reg:HI 30))])
274 (set (match_operand:ALL4A 0 "register_operand" "")
275 (reg:ALL4A 22))])
276
277 ;; "*divsa3.call" "*udivusa3.call"
278 (define_insn "*<code><mode>3.call"
279 [(set (reg:ALL4A 22)
280 (usdiv:ALL4A (reg:ALL4A 24)
281 (reg:ALL4A 18)))
282 (clobber (reg:HI 26))
283 (clobber (reg:HI 30))]
284 ""
285 "%~call __<code><mode>3"
286 [(set_attr "type" "xcall")
287 (set_attr "cc" "clobber")])
This page took 0.044385 seconds and 4 git commands to generate.