]>
Commit | Line | Data |
---|---|---|
c6243b4c | 1 | ;; XSTORMY16 Machine description template |
83ffe9cd | 2 | ;; Copyright (C) 1997-2023 Free Software Foundation, Inc. |
4b58290f GK |
3 | ;; Contributed by Red Hat, Inc. |
4 | ||
4dedfc09 | 5 | ;; This file is part of GCC. |
4b58290f | 6 | |
4dedfc09 | 7 | ;; GCC is free software; you can redistribute it and/or modify |
4b58290f | 8 | ;; it under the terms of the GNU General Public License as published by |
2f83c7d6 | 9 | ;; the Free Software Foundation; either version 3, or (at your option) |
4b58290f GK |
10 | ;; any later version. |
11 | ||
4dedfc09 | 12 | ;; GCC is distributed in the hope that it will be useful, |
4b58290f GK |
13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ;; GNU General Public License for more details. | |
16 | ||
17 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. | |
4b58290f GK |
20 | |
21 | ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. | |
22 | ||
e7e09ad8 DD |
23 | ;; Constraints |
24 | ;; a $0 | |
25 | ;; b $1 | |
26 | ;; c $2 | |
27 | ;; d $8 | |
28 | ;; e $0..$7 | |
29 | ;; t $0..$1 | |
e7e09ad8 DD |
30 | ;; z $8..$9 |
31 | ;; I 0..3 | |
32 | ;; J 2**N mask | |
33 | ;; K 2**N antimask | |
34 | ;; L 0..255 | |
35 | ;; M -255..0 | |
36 | ;; N -3..0 | |
37 | ;; O 1..4 | |
38 | ;; P -4..-1 | |
39 | ;; Q post-inc mem (push) | |
40 | ;; R pre-dec mem (pop) | |
41 | ;; S immediate mem | |
42 | ;; T Rx | |
43 | ;; U -inf..1 or 16..inf | |
44 | ;; Z 0 | |
45 | ||
d40ba0b6 NC |
46 | (define_constants |
47 | [ | |
48 | (CARRY_REG 16) | |
49 | ] | |
50 | ) | |
4b58290f GK |
51 | \f |
52 | ;; :::::::::::::::::::: | |
53 | ;; :: | |
54 | ;; :: Attributes | |
55 | ;; :: | |
56 | ;; :::::::::::::::::::: | |
57 | ||
58 | ; Categorize branches for the conditional in the length attribute. | |
5ab9749e | 59 | (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4" |
4b58290f GK |
60 | (const_string "notdirectbranch")) |
61 | ||
62 | ; The length of an instruction, used for branch shortening. | |
5ab9749e | 63 | (define_attr "length" "" |
4b58290f GK |
64 | (cond |
65 | [(eq_attr "branch_class" "br12") | |
66 | (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046)) | |
67 | (lt (minus (match_dup 0) (pc)) (const_int 2048))) | |
68 | (const_int 2) | |
69 | (const_int 4)) | |
70 | (eq_attr "branch_class" "bcc12") | |
71 | (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) | |
72 | (lt (minus (match_dup 0) (pc)) (const_int 2048))) | |
73 | (const_int 4) | |
74 | (const_int 8)) | |
75 | (eq_attr "branch_class" "bcc8p2") | |
76 | (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124)) | |
77 | (lt (minus (match_dup 0) (pc)) (const_int 128))) | |
78 | (const_int 4) | |
79 | (const_int 8)) | |
80 | (eq_attr "branch_class" "bcc8p4") | |
81 | (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122)) | |
82 | (lt (minus (match_dup 0) (pc)) (const_int 128))) | |
83 | (const_int 6) | |
84 | (const_int 10))] | |
85 | (const_int 2))) | |
86 | ||
87 | ; The operand which determines the setting of Rpsw. | |
88 | ; The numbers indicate the operand number, | |
89 | ; 'clobber' indicates it is changed in some unspecified way | |
90 | ; 'nop' means it is not changed. | |
91 | (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0")) | |
92 | ||
93 | (define_asm_attributes [(set_attr "length" "4") | |
94 | (set_attr "psw_operand" "clobber")]) | |
95 | ||
25af5506 | 96 | (include "predicates.md") |
d634083b | 97 | (include "constraints.md") |
4b58290f GK |
98 | \f |
99 | ;; :::::::::::::::::::: | |
100 | ;; :: | |
101 | ;; :: Moves | |
102 | ;; :: | |
103 | ;; :::::::::::::::::::: | |
5ee4950e AH |
104 | ;; push/pop qi and hi are here as separate insns rather than part of |
105 | ;; the movqi/hi patterns because we need to ensure that reload isn't | |
106 | ;; passed anything it can't cope with. Without these patterns, we | |
107 | ;; might end up with | |
108 | ||
109 | ;; (set (mem (post_inc (sp))) mem (post_inc (reg))) | |
110 | ||
111 | ;; If, in this example, reg needs reloading, reload will read reg from | |
112 | ;; the stack , adjust sp, and store reg back at what is now the wrong | |
113 | ;; offset. By using separate patterns for push and pop we ensure that | |
114 | ;; insns like this one are never generated. | |
115 | ||
76f56a4d | 116 | (define_insn "pushqi1" |
4b156fd0 | 117 | [(set (mem:QI (post_inc:HI (reg:HI 15))) |
5ee4950e AH |
118 | (match_operand:QI 0 "register_operand" "r"))] |
119 | "" | |
120 | "push %0" | |
121 | [(set_attr "psw_operand" "nop") | |
122 | (set_attr "length" "2")]) | |
123 | ||
76f56a4d | 124 | (define_insn "popqi1" |
5ee4950e | 125 | [(set (match_operand:QI 0 "register_operand" "=r") |
4b156fd0 | 126 | (mem:QI (pre_dec:HI (reg:HI 15))))] |
5ee4950e AH |
127 | "" |
128 | "pop %0" | |
129 | [(set_attr "psw_operand" "nop") | |
130 | (set_attr "length" "2")]) | |
4b58290f GK |
131 | |
132 | (define_expand "movqi" | |
5ee4950e | 133 | [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "") |
4b58290f GK |
134 | (match_operand:QI 1 "general_operand" ""))] |
135 | "" | |
5ab9749e NC |
136 | { xstormy16_expand_move (QImode, operands[0], operands[1]); |
137 | DONE; | |
138 | }) | |
4b58290f | 139 | |
54e9a19d | 140 | (define_insn "movqi_internal" |
015e1120 DD |
141 | [(set (match_operand:QI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e") |
142 | (match_operand:QI 1 "general_operand" "r,e,m,i,i,i,i,ie,W"))] | |
4b58290f GK |
143 | "" |
144 | "@ | |
145 | mov %0,%1 | |
4b58290f GK |
146 | mov.b %0,%1 |
147 | mov.b %0,%1 | |
148 | mov %0,%1 | |
149 | mov Rx,%1 | |
150 | mov %0,%1 | |
54e9a19d DD |
151 | mov.b %0,%1 |
152 | mov.b %0,%1 | |
4b58290f | 153 | mov.b %0,%1" |
5ab9749e | 154 | [(set_attr_alternative "length" |
4b58290f | 155 | [(const_int 2) |
4b58290f GK |
156 | (if_then_else (match_operand:QI 0 "short_memory_operand" "") |
157 | (const_int 2) | |
158 | (const_int 4)) | |
159 | (if_then_else (match_operand:QI 1 "short_memory_operand" "") | |
160 | (const_int 2) | |
161 | (const_int 4)) | |
162 | (const_int 2) | |
163 | (const_int 2) | |
164 | (const_int 4) | |
54e9a19d DD |
165 | (const_int 4) |
166 | (const_int 2) | |
167 | (const_int 2)]) | |
168 | (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")]) | |
5ee4950e | 169 | |
76f56a4d | 170 | (define_insn "pushhi1" |
4b156fd0 | 171 | [(set (mem:HI (post_inc:HI (reg:HI 15))) |
5ee4950e AH |
172 | (match_operand:HI 0 "register_operand" "r"))] |
173 | "" | |
174 | "push %0" | |
175 | [(set_attr "psw_operand" "nop") | |
176 | (set_attr "length" "2")]) | |
177 | ||
76f56a4d | 178 | (define_insn "pophi1" |
5ee4950e | 179 | [(set (match_operand:HI 0 "register_operand" "=r") |
4b156fd0 | 180 | (mem:HI (pre_dec:HI (reg:HI 15))))] |
5ee4950e AH |
181 | "" |
182 | "pop %0" | |
183 | [(set_attr "psw_operand" "nop") | |
184 | (set_attr "length" "2")]) | |
4b58290f GK |
185 | |
186 | (define_expand "movhi" | |
5ee4950e | 187 | [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "") |
60a4dfd6 | 188 | (match_operand:HI 1 "general_operand" ""))] |
4b58290f | 189 | "" |
5ab9749e NC |
190 | { xstormy16_expand_move (HImode, operands[0], operands[1]); |
191 | DONE; | |
192 | }) | |
4b58290f | 193 | |
54e9a19d | 194 | (define_insn "movhi_internal" |
015e1120 | 195 | [(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,e") |
60a4dfd6 | 196 | (match_operand:HI 1 "general_operand" "r,e,m,L,L,i,i,ie,W"))] |
4b58290f GK |
197 | "" |
198 | "@ | |
199 | mov %0,%1 | |
4b58290f GK |
200 | mov.w %0,%1 |
201 | mov.w %0,%1 | |
202 | mov.w %0,%1 | |
203 | mov.w Rx,%1 | |
204 | mov.w %0,%1 | |
54e9a19d DD |
205 | mov.w %0,%1 |
206 | mov.w %0,%1 | |
4b58290f | 207 | mov.w %0,%1" |
5ab9749e | 208 | [(set_attr_alternative "length" |
4b58290f | 209 | [(const_int 2) |
4b58290f GK |
210 | (if_then_else (match_operand:QI 0 "short_memory_operand" "") |
211 | (const_int 2) | |
212 | (const_int 4)) | |
213 | (if_then_else (match_operand:QI 1 "short_memory_operand" "") | |
214 | (const_int 2) | |
215 | (const_int 4)) | |
216 | (const_int 2) | |
217 | (const_int 2) | |
218 | (const_int 4) | |
54e9a19d DD |
219 | (const_int 4) |
220 | (const_int 4) | |
4b58290f | 221 | (const_int 4)]) |
54e9a19d | 222 | (set_attr "psw_operand" "0,0,0,0,nop,0,nop,0,0")]) |
4b58290f GK |
223 | |
224 | (define_expand "movsi" | |
225 | [(set (match_operand:SI 0 "nonimmediate_operand" "") | |
226 | (match_operand:SI 1 "general_operand" ""))] | |
227 | "" | |
5ab9749e NC |
228 | { xstormy16_expand_move (SImode, operands[0], operands[1]); |
229 | DONE; | |
230 | }) | |
4b58290f GK |
231 | |
232 | (define_insn_and_split "*movsi_internal" | |
233 | [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Q,r,m,e,&e,e,r,S") | |
234 | (match_operand:SI 1 "general_operand" "r,r,R,e,o, V,L,i,i"))] | |
235 | "" | |
236 | "#" | |
237 | "reload_completed" | |
238 | [(pc)] | |
5ab9749e NC |
239 | { xstormy16_split_move (SImode, operands[0], operands[1]); |
240 | DONE; | |
241 | } | |
242 | [(set_attr_alternative "length" | |
4b58290f GK |
243 | [(const_int 4) |
244 | (const_int 4) | |
245 | (const_int 4) | |
246 | (if_then_else (match_operand:QI 0 "short_memory_operand" "") | |
247 | (const_int 6) | |
248 | (const_int 8)) | |
249 | (if_then_else (match_operand:QI 1 "short_memory_operand" "") | |
250 | (const_int 6) | |
251 | (const_int 8)) | |
252 | (if_then_else (match_operand:QI 1 "short_memory_operand" "") | |
253 | (const_int 6) | |
254 | (const_int 8)) | |
255 | (const_int 4) | |
256 | (const_int 8) | |
257 | (const_int 8)])]) | |
4b58290f GK |
258 | \f |
259 | ;; :::::::::::::::::::: | |
260 | ;; :: | |
261 | ;; :: Conversions | |
262 | ;; :: | |
263 | ;; :::::::::::::::::::: | |
264 | ||
265 | (define_insn "extendqihi2" | |
266 | [(set (match_operand:HI 0 "register_operand" "=r") | |
267 | (sign_extend:HI (match_operand:QI 1 "register_operand" "0")))] | |
268 | "" | |
269 | "cbw %0") | |
270 | ||
515342a8 AH |
271 | (define_insn "zero_extendqihi2" |
272 | [(set (match_operand:HI 0 "register_operand" "=e,r") | |
273 | (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,0")))] | |
274 | "" | |
275 | "@ | |
276 | mov.b %0, %1 | |
277 | shl %0,#8\n\tshr %0,#8" | |
278 | [(set_attr "psw_operand" "nop,0") | |
cf7442bb NC |
279 | (set_attr_alternative "length" |
280 | [(const_int 4) | |
281 | (const_int 8)])]) | |
4b58290f GK |
282 | \f |
283 | ;; :::::::::::::::::::: | |
284 | ;; :: | |
285 | ;; :: Bit field extraction | |
286 | ;; :: | |
287 | ;; :::::::::::::::::::: | |
288 | ||
289 | ;; Extract an unsigned bit field | |
290 | ;(define_insn "extzv" | |
291 | ; [(set (match_operand:SI 0 "register_operand" "=r") | |
292 | ; (zero_extract:SI (match_operand:SI 1 "register_operand" "r") | |
293 | ; (match_operand:SI 2 "const_int_operand" "n") | |
294 | ; (match_operand:SI 3 "const_int_operand" "n")))] | |
295 | ; "" | |
296 | ; "extzv %0,%1,%2,%3" | |
297 | ; [(set_attr "length" "4")]) | |
298 | ||
299 | ;; Insert a bit field | |
300 | ;(define_insn "insv" | |
301 | ; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") | |
302 | ; (match_operand:SI 1 "const_int_operand" "n") | |
303 | ; (match_operand:SI 2 "const_int_operand" "n")) | |
304 | ; (match_operand:SI 3 "nonmemory_operand" "ri"))] | |
305 | ; "" | |
306 | ; "insv %0,%1,%2,%3" | |
307 | ; [(set_attr "length" "4")]) | |
308 | ||
309 | \f | |
310 | ;; :::::::::::::::::::: | |
311 | ;; :: | |
a7b376ee | 312 | ;; :: 16-bit Integer arithmetic |
4b58290f GK |
313 | ;; :: |
314 | ;; :::::::::::::::::::: | |
315 | ||
316 | ;; Addition | |
f84fe9b6 NC |
317 | ; Note - the early clobber modifier is no longer needed on operand 3 |
318 | ; and in fact can cause some reload spill failures if it is present. | |
e7e09ad8 DD |
319 | ; Note that the 'Z' constraint matches "add $reg,0", which reload |
320 | ; will occasionally emit. We avoid the "add $reg,imm" match because | |
321 | ; it clobbers the carry. | |
4b58290f | 322 | (define_insn "addhi3" |
e7e09ad8 DD |
323 | [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r") |
324 | (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0") | |
325 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i"))) | |
d40ba0b6 | 326 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
327 | "" |
328 | "@ | |
329 | inc %0,%o2 | |
330 | dec %0,%O2 | |
e7e09ad8 | 331 | ; |
4b58290f GK |
332 | add Rx,%2 |
333 | sub Rx,#%n2 | |
334 | add %0,%2 | |
335 | sub %0,#%n2 | |
336 | add %0,%2" | |
e7e09ad8 | 337 | [(set_attr "length" "2,2,0,2,2,2,2,4")]) |
4b58290f | 338 | |
4b58290f GK |
339 | (define_insn "addchi4" |
340 | [(set (match_operand:HI 0 "register_operand" "=T,r,r") | |
341 | (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0") | |
f3922fd2 | 342 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i"))) |
d40ba0b6 | 343 | (set (reg:BI CARRY_REG) |
4b58290f GK |
344 | (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) |
345 | (zero_extend:SI (match_dup 2))) | |
346 | (const_int 16))))] | |
347 | "" | |
348 | "@ | |
349 | add Rx,%2 | |
350 | add %0,%2 | |
351 | add %0,%2" | |
352 | [(set_attr "length" "2,2,4")]) | |
353 | ||
354 | (define_insn "addchi5" | |
355 | [(set (match_operand:HI 0 "register_operand" "=T,r,r") | |
356 | (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0") | |
d40ba0b6 | 357 | (zero_extend:HI (reg:BI CARRY_REG))) |
f3922fd2 | 358 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i"))) |
5ab9749e NC |
359 | (set (reg:BI CARRY_REG) |
360 | (truncate:BI (lshiftrt:SI (plus:SI (plus:SI | |
4b58290f | 361 | (zero_extend:SI (match_dup 1)) |
d40ba0b6 | 362 | (zero_extend:SI (reg:BI CARRY_REG))) |
4b58290f GK |
363 | (zero_extend:SI (match_dup 2))) |
364 | (const_int 16))))] | |
365 | "" | |
366 | "@ | |
367 | adc Rx,%2 | |
368 | adc %0,%2 | |
369 | adc %0,%2" | |
370 | [(set_attr "length" "2,2,4")]) | |
371 | ||
372 | ;; Subtraction | |
373 | ; Operand 3 is marked earlyclobber because that helps reload | |
374 | ; to generate better code---this pattern will never need the | |
375 | ; carry register as an input, and some output reloads or input | |
376 | ; reloads might need to use it. In fact, without the '&' reload | |
377 | ; will fail in some cases. | |
378 | (define_insn "subhi3" | |
379 | [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r") | |
380 | (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0") | |
f3922fd2 | 381 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i"))) |
d40ba0b6 | 382 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
383 | "" |
384 | "@ | |
385 | dec %0,%o2 | |
386 | inc %0,%O2 | |
387 | sub Rx,%2 | |
388 | add Rx,#%n2 | |
389 | sub %0,%2 | |
390 | add %0,#%n2 | |
391 | sub %0,%2" | |
392 | [(set_attr "length" "2,2,2,2,2,2,4")]) | |
393 | ||
394 | (define_insn "subchi4" | |
395 | [(set (match_operand:HI 0 "register_operand" "=T,r,r") | |
396 | (minus:HI (match_operand:HI 1 "register_operand" "0,0,0") | |
f3922fd2 | 397 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i"))) |
5ab9749e | 398 | (set (reg:BI CARRY_REG) |
4b58290f GK |
399 | (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1)) |
400 | (zero_extend:SI (match_dup 2))) | |
401 | (const_int 16))))] | |
402 | "" | |
403 | "@ | |
404 | sub Rx,%2 | |
405 | sub %0,%2 | |
406 | sub %0,%2" | |
407 | [(set_attr "length" "2,2,4")]) | |
408 | ||
409 | (define_insn "subchi5" | |
410 | [(set (match_operand:HI 0 "register_operand" "=T,r,r") | |
411 | (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0") | |
5ab9749e | 412 | (zero_extend:HI (reg:BI CARRY_REG))) |
f3922fd2 | 413 | (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i"))) |
5ab9749e NC |
414 | (set (reg:BI CARRY_REG) |
415 | (truncate:BI (lshiftrt:SI (minus:SI (minus:SI | |
4b58290f | 416 | (zero_extend:SI (match_dup 1)) |
d40ba0b6 | 417 | (zero_extend:SI (reg:BI CARRY_REG))) |
4b58290f GK |
418 | (zero_extend:SI (match_dup 2))) |
419 | (const_int 16))))] | |
420 | "" | |
421 | "@ | |
422 | sbc Rx,%2 | |
423 | sbc %0,%2 | |
424 | sbc %0,%2" | |
425 | [(set_attr "length" "2,2,4")]) | |
426 | ||
427 | ; Basic multiplication | |
428 | (define_insn "mulhi3" | |
429 | [(set (match_operand:HI 0 "register_operand" "=a") | |
430 | (mult:HI (match_operand:HI 1 "register_operand" "%a") | |
431 | (match_operand:HI 2 "register_operand" "c"))) | |
432 | (clobber (match_scratch:HI 3 "=b")) | |
433 | ] | |
434 | "" | |
435 | "mul" | |
436 | [(set_attr "psw_operand" "nop")]) | |
437 | ||
a7b376ee | 438 | ;; Unsigned multiplication producing 64-bit results from 32-bit inputs |
4b58290f GK |
439 | ; The constraint on operand 0 is 't' because it is actually two regs |
440 | ; long, and both regs must match the constraint. | |
441 | (define_insn "umulhisi3" | |
442 | [(set (match_operand:SI 0 "register_operand" "=t") | |
443 | (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a")) | |
444 | (zero_extend:SI (match_operand:HI 2 "register_operand" "c")))) | |
445 | ] | |
446 | "" | |
447 | "mul" | |
448 | [(set_attr "psw_operand" "nop")]) | |
449 | ||
450 | ;; Unsigned division giving both quotient and remainder | |
451 | (define_insn "udivmodhi4" | |
452 | [(set (match_operand:HI 0 "register_operand" "=a") | |
ed09481d GK |
453 | (udiv:HI (match_operand:HI 1 "register_operand" "a") |
454 | (match_operand:HI 2 "register_operand" "c"))) | |
4b58290f | 455 | (set (match_operand:HI 3 "register_operand" "=b") |
ed09481d GK |
456 | (umod:HI (match_dup 1) |
457 | (match_dup 2)))] | |
4b58290f GK |
458 | "" |
459 | "div" | |
460 | [(set_attr "psw_operand" "nop")]) | |
461 | ||
3d4b192a DD |
462 | ;; Signed division giving both quotient and remainder |
463 | (define_insn "divmodhi4" | |
464 | [(set (match_operand:HI 0 "register_operand" "=a") | |
465 | (div:HI (match_operand:HI 1 "register_operand" "a") | |
466 | (match_operand:HI 2 "register_operand" "c"))) | |
467 | (set (match_operand:HI 3 "register_operand" "=b") | |
468 | (mod:HI (match_dup 1) | |
469 | (match_dup 2)))] | |
470 | "" | |
471 | "sdiv" | |
472 | [(set_attr "psw_operand" "nop")]) | |
473 | ||
474 | ;; Signed 32/16 division | |
475 | (define_insn "sdivlh" | |
476 | [(set (match_operand:HI 0 "register_operand" "=a") | |
477 | (div:HI (match_operand:SI 2 "register_operand" "t") | |
478 | (match_operand:HI 3 "register_operand" "c"))) | |
479 | (set (match_operand:HI 1 "register_operand" "=b") | |
480 | (mod:HI (match_dup 2) | |
481 | (match_dup 3)))] | |
482 | "" | |
483 | "sdivlh" | |
484 | [(set_attr "psw_operand" "nop")]) | |
485 | ||
486 | ;; Unsigned 32/16 division | |
487 | (define_insn "udivlh" | |
488 | [(set (match_operand:HI 0 "register_operand" "=a") | |
489 | (udiv:HI (match_operand:SI 2 "register_operand" "t") | |
490 | (match_operand:HI 3 "register_operand" "c"))) | |
491 | (set (match_operand:HI 1 "register_operand" "=b") | |
492 | (umod:HI (match_dup 2) | |
493 | (match_dup 3)))] | |
494 | "" | |
495 | "divlh" | |
496 | [(set_attr "psw_operand" "nop")]) | |
497 | ||
4b58290f GK |
498 | ;; Negation |
499 | ||
500 | (define_expand "neghi2" | |
501 | [(set (match_operand:HI 0 "register_operand" "") | |
502 | (not:HI (match_operand:HI 1 "register_operand" ""))) | |
503 | (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1))) | |
d40ba0b6 | 504 | (clobber (reg:BI CARRY_REG))])] |
4b58290f GK |
505 | "" |
506 | "") | |
4b58290f GK |
507 | \f |
508 | ;; :::::::::::::::::::: | |
509 | ;; :: | |
a7b376ee | 510 | ;; :: 16-bit Integer Shifts and Rotates |
4b58290f GK |
511 | ;; :: |
512 | ;; :::::::::::::::::::: | |
513 | ||
514 | ;; Arithmetic Shift Left | |
515 | (define_insn "ashlhi3" | |
516 | [(set (match_operand:HI 0 "register_operand" "=r") | |
517 | (ashift:HI (match_operand:HI 1 "register_operand" "0") | |
518 | (match_operand:HI 2 "nonmemory_operand" "ri"))) | |
d40ba0b6 | 519 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
520 | "" |
521 | "shl %0,%2") | |
522 | ||
523 | ;; Arithmetic Shift Right | |
524 | (define_insn "ashrhi3" | |
525 | [(set (match_operand:HI 0 "register_operand" "=r") | |
526 | (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") | |
527 | (match_operand:HI 2 "nonmemory_operand" "ri"))) | |
d40ba0b6 | 528 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
529 | "" |
530 | "asr %0,%2") | |
531 | ||
532 | ;; Logical Shift Right | |
533 | (define_insn "lshrhi3" | |
534 | [(set (match_operand:HI 0 "register_operand" "=r") | |
535 | (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") | |
536 | (match_operand:HI 2 "nonmemory_operand" "ri"))) | |
d40ba0b6 | 537 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
538 | "" |
539 | "shr %0,%2") | |
4b58290f GK |
540 | \f |
541 | ;; :::::::::::::::::::: | |
542 | ;; :: | |
a7b376ee | 543 | ;; :: 16-Bit Integer Logical operations |
4b58290f GK |
544 | ;; :: |
545 | ;; :::::::::::::::::::: | |
546 | ||
a7b376ee | 547 | ;; Logical AND, 16-bit integers |
4b58290f | 548 | (define_insn "andhi3" |
54e9a19d DD |
549 | [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W") |
550 | (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0") | |
551 | (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))] | |
4b58290f GK |
552 | "" |
553 | "@ | |
554 | and Rx,%2 | |
555 | and %0,%2 | |
556 | clr1 %0,%B2 | |
54e9a19d DD |
557 | and %0,%2 |
558 | #" | |
559 | [(set_attr "length" "2,2,2,4,2")]) | |
560 | ||
561 | (define_split | |
562 | [(set (match_operand:HI 0 "xstormy16_below100_operand" "") | |
563 | (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "") | |
564 | (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))] | |
565 | "" | |
566 | [(set (match_dup 3) | |
567 | (and:QI (match_dup 4) | |
568 | (match_dup 5)))] | |
5ab9749e NC |
569 | { int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0; |
570 | operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s); | |
571 | operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s); | |
572 | operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s); | |
573 | operands[5] = GEN_INT (INTVAL (operands[5]) | ~ (HOST_WIDE_INT) 0xff); | |
574 | }) | |
4b58290f | 575 | |
a7b376ee | 576 | ;; Inclusive OR, 16-bit integers |
4b58290f | 577 | (define_insn "iorhi3" |
54e9a19d DD |
578 | [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W") |
579 | (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0") | |
580 | (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))] | |
4b58290f GK |
581 | "" |
582 | "@ | |
583 | or Rx,%2 | |
584 | or %0,%2 | |
585 | set1 %0,%B2 | |
54e9a19d DD |
586 | or %0,%2 |
587 | #" | |
588 | [(set_attr "length" "2,2,2,4,2")]) | |
589 | ||
590 | (define_split | |
591 | [(set (match_operand:HI 0 "xstormy16_below100_operand" "") | |
592 | (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "") | |
593 | (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))] | |
594 | "" | |
595 | [(set (match_dup 3) | |
596 | (ior:QI (match_dup 4) | |
597 | (match_dup 5)))] | |
5ab9749e NC |
598 | { int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0; |
599 | operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s); | |
600 | operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s); | |
601 | operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s); | |
602 | operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff); | |
603 | }) | |
4b58290f | 604 | |
a7b376ee | 605 | ;; Exclusive OR, 16-bit integers |
4b58290f GK |
606 | (define_insn "xorhi3" |
607 | [(set (match_operand:HI 0 "register_operand" "=T,r,r") | |
608 | (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0") | |
609 | (match_operand:HI 2 "nonmemory_operand" "L,r,i")))] | |
610 | "" | |
611 | "@ | |
612 | xor Rx,%2 | |
613 | xor %0,%2 | |
614 | xor %0,%2" | |
615 | [(set_attr "length" "2,2,4")]) | |
616 | ||
a7b376ee | 617 | ;; One's complement, 16-bit integers |
4b58290f GK |
618 | (define_insn "one_cmplhi2" |
619 | [(set (match_operand:HI 0 "register_operand" "=r") | |
620 | (not:HI (match_operand:HI 1 "register_operand" "0")))] | |
621 | "" | |
622 | "not %0") | |
4b58290f GK |
623 | \f |
624 | ;; :::::::::::::::::::: | |
625 | ;; :: | |
a7b376ee | 626 | ;; :: 32-bit Integer arithmetic |
4b58290f GK |
627 | ;; :: |
628 | ;; :::::::::::::::::::: | |
629 | ||
630 | ;; Addition | |
631 | (define_insn_and_split "addsi3" | |
632 | [(set (match_operand:SI 0 "register_operand" "=r") | |
633 | (plus:SI (match_operand:SI 1 "register_operand" "%0") | |
634 | (match_operand:SI 2 "nonmemory_operand" "ri"))) | |
d40ba0b6 | 635 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
636 | "" |
637 | "#" | |
638 | "reload_completed" | |
639 | [(pc)] | |
5ab9749e NC |
640 | { xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1], |
641 | operands[2]); | |
642 | DONE; | |
643 | } | |
4b58290f GK |
644 | [(set_attr "length" "4")]) |
645 | ||
646 | ;; Subtraction | |
647 | (define_insn_and_split "subsi3" | |
648 | [(set (match_operand:SI 0 "register_operand" "=r") | |
649 | (minus:SI (match_operand:SI 1 "register_operand" "0") | |
650 | (match_operand:SI 2 "nonmemory_operand" "ri"))) | |
d40ba0b6 | 651 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
652 | "" |
653 | "#" | |
654 | "reload_completed" | |
655 | [(pc)] | |
5ab9749e NC |
656 | { xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1], |
657 | operands[2]); | |
658 | DONE; | |
659 | } | |
4b58290f GK |
660 | [(set_attr "length" "4")]) |
661 | ||
662 | (define_expand "negsi2" | |
9be13211 DD |
663 | [(parallel [(set (match_operand:SI 0 "register_operand" "") |
664 | (neg:SI (match_operand:SI 1 "register_operand" ""))) | |
d40ba0b6 | 665 | (clobber (reg:BI CARRY_REG))])] |
9be13211 | 666 | "" |
5ab9749e | 667 | { operands[2] = gen_reg_rtx (HImode); }) |
9be13211 DD |
668 | |
669 | (define_insn_and_split "*negsi2_internal" | |
670 | [(set (match_operand:SI 0 "register_operand" "=&r") | |
671 | (neg:SI (match_operand:SI 1 "register_operand" "r"))) | |
d40ba0b6 | 672 | (clobber (reg:BI CARRY_REG))] |
4b58290f | 673 | "" |
9be13211 DD |
674 | "#" |
675 | "reload_completed" | |
676 | [(pc)] | |
5ab9749e NC |
677 | { xstormy16_expand_arith (SImode, NEG, operands[0], operands[0], |
678 | operands[1]); | |
679 | DONE; | |
680 | }) | |
4b58290f GK |
681 | |
682 | ;; :::::::::::::::::::: | |
683 | ;; :: | |
a7b376ee | 684 | ;; :: 32-bit Integer Shifts and Rotates |
4b58290f GK |
685 | ;; :: |
686 | ;; :::::::::::::::::::: | |
687 | ||
688 | ;; Arithmetic Shift Left | |
689 | (define_expand "ashlsi3" | |
690 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
691 | (ashift:SI (match_operand:SI 1 "register_operand" "") | |
692 | (match_operand:SI 2 "const_int_operand" ""))) | |
d40ba0b6 NC |
693 | (clobber (reg:BI CARRY_REG)) |
694 | (clobber (match_dup 3))])] | |
4b58290f | 695 | "" |
5ab9749e | 696 | { if (! const_int_operand (operands[2], SImode)) |
d40ba0b6 | 697 | FAIL; |
5ab9749e NC |
698 | operands[3] = gen_reg_rtx (HImode); |
699 | }) | |
4b58290f GK |
700 | |
701 | ;; Arithmetic Shift Right | |
702 | (define_expand "ashrsi3" | |
703 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
704 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "") | |
705 | (match_operand:SI 2 "const_int_operand" ""))) | |
d40ba0b6 NC |
706 | (clobber (reg:BI CARRY_REG)) |
707 | (clobber (match_dup 3))])] | |
4b58290f | 708 | "" |
5ab9749e | 709 | { if (! const_int_operand (operands[2], SImode)) |
d40ba0b6 | 710 | FAIL; |
5ab9749e NC |
711 | operands[3] = gen_reg_rtx (HImode); |
712 | }) | |
4b58290f GK |
713 | |
714 | ;; Logical Shift Right | |
715 | (define_expand "lshrsi3" | |
716 | [(parallel [(set (match_operand:SI 0 "register_operand" "") | |
717 | (lshiftrt:SI (match_operand:SI 1 "register_operand" "") | |
718 | (match_operand:SI 2 "const_int_operand" ""))) | |
d40ba0b6 NC |
719 | (clobber (reg:BI CARRY_REG)) |
720 | (clobber (match_dup 3))])] | |
4b58290f | 721 | "" |
5ab9749e | 722 | { if (! const_int_operand (operands[2], SImode)) |
d40ba0b6 | 723 | FAIL; |
5ab9749e NC |
724 | operands[3] = gen_reg_rtx (HImode); |
725 | }) | |
4b58290f GK |
726 | |
727 | (define_insn "*shiftsi" | |
728 | [(set (match_operand:SI 0 "register_operand" "=r,r") | |
d40ba0b6 | 729 | (match_operator:SI 4 "shift_operator" |
4b58290f GK |
730 | [(match_operand:SI 1 "register_operand" "0,0") |
731 | (match_operand:SI 2 "const_int_operand" "U,n")])) | |
d40ba0b6 NC |
732 | (clobber (reg:BI CARRY_REG)) |
733 | (clobber (match_operand:HI 3 "" "=X,r"))] | |
4b58290f | 734 | "" |
5ab9749e | 735 | "* return xstormy16_output_shift (SImode, GET_CODE (operands[4]), |
d40ba0b6 | 736 | operands[0], operands[2], operands[3]);" |
4b58290f GK |
737 | [(set_attr "length" "6,10") |
738 | (set_attr "psw_operand" "clobber,clobber")]) | |
4b58290f | 739 | |
4b58290f GK |
740 | \f |
741 | ;; :::::::::::::::::::: | |
742 | ;; :: | |
743 | ;; :: Branches | |
744 | ;; :: | |
745 | ;; :::::::::::::::::::: | |
746 | ||
f90b7a5a PB |
747 | (define_expand "cbranchhi4" |
748 | [(set (pc) | |
749 | (if_then_else (match_operator 0 "comparison_operator" | |
750 | [(match_operand:HI 1 "register_operand" "") | |
751 | (match_operand:HI 2 "nonmemory_operand" "")]) | |
752 | (label_ref (match_operand 3 "" "")) | |
753 | (pc))) | |
754 | (clobber (reg:BI CARRY_REG))] | |
4b58290f | 755 | "" |
f90b7a5a PB |
756 | { |
757 | xstormy16_emit_cbranch (GET_CODE (operands[0]), operands[1], operands[2], | |
758 | operands[3]); | |
759 | DONE; | |
760 | }) | |
4b58290f | 761 | |
54e9a19d | 762 | (define_insn "cbranchhi" |
5ab9749e | 763 | [(set (pc) |
4b58290f | 764 | (if_then_else (match_operator:HI 1 "comparison_operator" |
5ab9749e | 765 | [(match_operand:HI 2 "nonmemory_operand" |
4b58290f GK |
766 | "r,e,L") |
767 | (match_operand:HI 3 "nonmemory_operand" | |
768 | "r,L,e")]) | |
769 | (label_ref (match_operand 0 "" "")) | |
770 | (pc))) | |
d40ba0b6 | 771 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
772 | "" |
773 | "* | |
774 | { | |
c6243b4c | 775 | return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn); |
4b58290f GK |
776 | }" |
777 | [(set_attr "branch_class" "bcc12") | |
778 | (set_attr "psw_operand" "0,0,1")]) | |
779 | ||
54e9a19d | 780 | (define_insn "cbranchhi_neg" |
5ab9749e | 781 | [(set (pc) |
4b58290f | 782 | (if_then_else (match_operator:HI 1 "comparison_operator" |
5ab9749e | 783 | [(match_operand:HI 2 "nonmemory_operand" |
4b58290f GK |
784 | "r,e,L") |
785 | (match_operand:HI 3 "nonmemory_operand" | |
786 | "r,L,e")]) | |
787 | (pc) | |
788 | (label_ref (match_operand 0 "" "")))) | |
d40ba0b6 | 789 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
790 | "" |
791 | "* | |
792 | { | |
c6243b4c | 793 | return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn); |
4b58290f GK |
794 | }" |
795 | [(set_attr "branch_class" "bcc12") | |
796 | (set_attr "psw_operand" "0,0,1")]) | |
797 | ||
798 | (define_insn "*eqbranchsi" | |
799 | [(set (pc) | |
800 | (if_then_else (match_operator:SI 1 "equality_operator" | |
5ab9749e | 801 | [(match_operand:SI 2 "register_operand" |
f3922fd2 | 802 | "r") |
4b58290f GK |
803 | (const_int 0)]) |
804 | (label_ref (match_operand 0 "" "")) | |
805 | (pc))) | |
2ccd9cb2 | 806 | (clobber (match_operand:SI 3 "register_operand" "=2"))] |
4b58290f GK |
807 | "" |
808 | "* | |
809 | { | |
c6243b4c | 810 | return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn); |
4b58290f GK |
811 | }" |
812 | [(set_attr "branch_class" "bcc8p2") | |
813 | (set_attr "psw_operand" "clobber")]) | |
814 | ||
4b58290f GK |
815 | (define_insn "*ineqbranch_1" |
816 | [(set (pc) | |
d40ba0b6 NC |
817 | (if_then_else (match_operator:HI 4 "xstormy16_ineqsi_operator" |
818 | [(minus:HI (match_operand:HI 1 "register_operand" "T,r,r") | |
819 | (zero_extend:HI (reg:BI CARRY_REG))) | |
85d04fa2 | 820 | (match_operand:HI 3 "nonmemory_operand" "L,r,i")]) |
4b58290f GK |
821 | (label_ref (match_operand 0 "" "")) |
822 | (pc))) | |
f3922fd2 | 823 | (set (match_operand:HI 2 "register_operand" "=1,1,1") |
d40ba0b6 | 824 | (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (reg:BI CARRY_REG))) |
4b58290f | 825 | (match_dup 3))) |
d40ba0b6 | 826 | (clobber (reg:BI CARRY_REG))] |
4b58290f GK |
827 | "" |
828 | "* | |
829 | { | |
d40ba0b6 | 830 | return xstormy16_output_cbranch_si (operands[4], \"%l0\", 0, insn); |
4b58290f GK |
831 | }" |
832 | [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4") | |
833 | (set_attr "psw_operand" "2,2,2")]) | |
4b58290f GK |
834 | \f |
835 | ;; :::::::::::::::::::: | |
836 | ;; :: | |
837 | ;; :: Call and branch instructions | |
838 | ;; :: | |
839 | ;; :::::::::::::::::::: | |
840 | ||
841 | ;; Subroutine call instruction returning no value. Operand 0 is the function | |
842 | ;; to call; operand 1 is the number of bytes of arguments pushed (in mode | |
843 | ;; `SImode', except it is normally a `const_int'); operand 2 is the number of | |
844 | ;; registers used as operands. | |
845 | ||
846 | ;; On most machines, operand 2 is not actually stored into the RTL pattern. It | |
847 | ;; is supplied for the sake of some RISC machines which need to put this | |
848 | ;; information into the assembler code; they can put it in the RTL instead of | |
849 | ;; operand 1. | |
850 | ||
851 | (define_expand "call" | |
852 | [(call (match_operand:HI 0 "memory_operand" "m") | |
853 | (match_operand 1 "" "")) | |
854 | (use (match_operand 2 "immediate_operand" ""))] | |
855 | "" | |
c6243b4c | 856 | "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;") |
4b58290f GK |
857 | |
858 | ;; Subroutine call instruction returning a value. Operand 0 is the hard | |
859 | ;; register in which the value is returned. There are three more operands, the | |
860 | ;; same as the three operands of the `call' instruction (but with numbers | |
861 | ;; increased by one). | |
862 | ||
863 | ;; Subroutines that return `BLKmode' objects use the `call' insn. | |
864 | ||
865 | (define_expand "call_value" | |
866 | [(set (match_operand 0 "register_operand" "=r") | |
867 | (call (match_operand:HI 1 "memory_operand" "m") | |
868 | (match_operand:SI 2 "" ""))) | |
869 | (use (match_operand 3 "immediate_operand" ""))] | |
870 | "" | |
c6243b4c | 871 | "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;") |
4b58290f GK |
872 | |
873 | (define_insn "*call_internal" | |
874 | [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r")) | |
875 | (match_operand 1 "" "")) | |
da6e254e | 876 | (use (match_operand:HI 2 "nonmemory_operand" "X,z"))] |
4b58290f GK |
877 | "" |
878 | "@ | |
879 | callf %C0 | |
880 | call %2,%0" | |
881 | [(set_attr "length" "4,2") | |
882 | (set_attr "psw_operand" "clobber")]) | |
883 | ||
884 | (define_insn "*call_value_internal" | |
885 | [(set (match_operand 3 "register_operand" "=r,r") | |
886 | (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r")) | |
887 | (match_operand 1 "" ""))) | |
da6e254e | 888 | (use (match_operand:HI 2 "nonmemory_operand" "X,z"))] |
4b58290f GK |
889 | "" |
890 | "@ | |
891 | callf %C0 | |
892 | call %2,%0" | |
893 | [(set_attr "length" "4,2") | |
894 | (set_attr "psw_operand" "clobber")]) | |
895 | ||
896 | ;; Subroutine return | |
897 | (define_expand "return" | |
898 | [(return)] | |
899 | "direct_return()" | |
900 | "") | |
901 | ||
902 | (define_insn "return_internal" | |
903 | [(return)] | |
904 | "" | |
905 | "ret" | |
906 | [(set_attr "psw_operand" "nop")]) | |
907 | ||
908 | (define_insn "return_internal_interrupt" | |
909 | [(return) | |
910 | (unspec_volatile [(const_int 0)] 1)] | |
911 | "" | |
912 | "iret" | |
913 | [(set_attr "psw_operand" "clobber")]) | |
914 | ||
915 | ;; Normal unconditional jump | |
916 | (define_insn "jump" | |
917 | [(set (pc) (label_ref (match_operand 0 "" "")))] | |
918 | "" | |
919 | "* | |
920 | { | |
c6243b4c | 921 | return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn); |
4b58290f GK |
922 | }" |
923 | [(set_attr "branch_class" "br12") | |
924 | (set_attr "psw_operand" "nop")]) | |
925 | ||
926 | ;; Indirect jump through a register | |
927 | (define_expand "indirect_jump" | |
928 | [(set (match_dup 1) (const_int 0)) | |
d40ba0b6 | 929 | (parallel [(set (pc) (match_operand:HI 0 "register_operand" "")) |
4b58290f GK |
930 | (use (match_dup 1))])] |
931 | "" | |
932 | "operands[1] = gen_reg_rtx (HImode);") | |
933 | ||
934 | (define_insn "" | |
935 | [(set (pc) (match_operand:HI 0 "register_operand" "r")) | |
da6e254e | 936 | (use (match_operand:HI 1 "register_operand" "z"))] |
4b58290f GK |
937 | "" |
938 | "jmp %1,%0" | |
939 | [(set_attr "length" "4") | |
940 | (set_attr "psw_operand" "nop")]) | |
941 | ||
942 | ;; Table-based switch statements. | |
943 | (define_expand "casesi" | |
944 | [(use (match_operand:SI 0 "register_operand" "")) | |
945 | (use (match_operand:SI 1 "immediate_operand" "")) | |
946 | (use (match_operand:SI 2 "immediate_operand" "")) | |
947 | (use (label_ref (match_operand 3 "" ""))) | |
948 | (use (label_ref (match_operand 4 "" "")))] | |
949 | "" | |
950 | " | |
951 | { | |
c6243b4c | 952 | xstormy16_expand_casesi (operands[0], operands[1], operands[2], |
4b58290f GK |
953 | operands[3], operands[4]); |
954 | DONE; | |
955 | }") | |
956 | ||
957 | (define_insn "tablejump_pcrel" | |
5ab9749e | 958 | [(set (pc) (mem:HI (plus:HI (pc) |
3d8dd3c0 | 959 | (match_operand:HI 0 "register_operand" "r")))) |
4b58290f GK |
960 | (use (label_ref:SI (match_operand 1 "" "")))] |
961 | "" | |
962 | "br %0" | |
963 | [(set_attr "psw_operand" "nop")]) | |
4b58290f GK |
964 | \f |
965 | ;; :::::::::::::::::::: | |
966 | ;; :: | |
967 | ;; :: Prologue and Epilogue instructions | |
968 | ;; :: | |
969 | ;; :::::::::::::::::::: | |
970 | ||
41441dc7 NB |
971 | ;; Called after register allocation to add any instructions needed for |
972 | ;; the prologue. Using a prologue insn is favored compared to putting | |
973 | ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro, | |
974 | ;; since it allows the scheduler to intermix instructions with the | |
975 | ;; saves of the caller saved registers. In some cases, it might be | |
976 | ;; necessary to emit a barrier instruction as the last insn to prevent | |
977 | ;; such scheduling. | |
4b58290f GK |
978 | (define_expand "prologue" |
979 | [(const_int 1)] | |
980 | "" | |
5ab9749e NC |
981 | { |
982 | xstormy16_expand_prologue (); | |
983 | DONE; | |
984 | }) | |
4b58290f | 985 | |
41441dc7 | 986 | ;; Called after register allocation to add any instructions needed for |
e03f5d43 | 987 | ;; the epilogue. Using an epilogue insn is favored compared to putting |
41441dc7 NB |
988 | ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro, |
989 | ;; since it allows the scheduler to intermix instructions with the | |
aabcd309 | 990 | ;; restores of the caller saved registers. In some cases, it might be |
41441dc7 NB |
991 | ;; necessary to emit a barrier instruction as the first insn to |
992 | ;; prevent such scheduling. | |
4b58290f GK |
993 | (define_expand "epilogue" |
994 | [(const_int 2)] | |
995 | "" | |
5ab9749e NC |
996 | { |
997 | xstormy16_expand_epilogue (); | |
998 | DONE; | |
999 | }) | |
4b58290f GK |
1000 | \f |
1001 | ;; :::::::::::::::::::: | |
1002 | ;; :: | |
1003 | ;; :: Miscellaneous instructions | |
1004 | ;; :: | |
1005 | ;; :::::::::::::::::::: | |
1006 | ||
1007 | ;; No operation, needed in case the user uses -g but not -O. | |
1008 | (define_insn "nop" | |
1009 | [(const_int 0)] | |
1010 | "" | |
1011 | "nop" | |
1012 | [(set_attr "psw_operand" "nop")]) | |
1013 | ||
1014 | ;; Pseudo instruction that prevents the scheduler from moving code above this | |
1015 | ;; point. | |
1016 | (define_insn "blockage" | |
1017 | [(unspec_volatile [(const_int 0)] 0)] | |
1018 | "" | |
1019 | "" | |
1020 | [(set_attr "length" "0") | |
1021 | (set_attr "psw_operand" "nop")]) | |
54e9a19d DD |
1022 | |
1023 | ;;--------------------------------------------------------------------------- | |
1024 | ||
1025 | (define_expand "iorqi3" | |
1026 | [(match_operand:QI 0 "xstormy16_below100_or_register" "") | |
1027 | (match_operand:QI 1 "xstormy16_below100_or_register" "") | |
1028 | (match_operand:QI 2 "nonmemory_operand" "")] | |
1029 | "" | |
5ab9749e NC |
1030 | { |
1031 | xstormy16_expand_iorqi3 (operands); | |
1032 | DONE; | |
1033 | }) | |
54e9a19d DD |
1034 | |
1035 | (define_insn "iorqi3_internal" | |
1036 | [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr") | |
1037 | (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0") | |
1038 | (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))] | |
1039 | "" | |
1040 | "set1 %0,%B2" | |
1041 | [(set_attr "length" "2") | |
1042 | (set_attr "psw_operand" "0")]) | |
1043 | ||
1044 | (define_peephole2 | |
1045 | [(set (match_operand:QI 0 "register_operand" "") | |
1046 | (match_operand:QI 1 "xstormy16_below100_operand" "")) | |
1047 | (set (match_operand:HI 2 "register_operand" "") | |
1048 | (ior:HI (match_operand:HI 3 "register_operand" "") | |
1049 | (match_operand:QI 4 "xstormy16_onebit_set_operand" ""))) | |
1050 | (set (match_operand:QI 5 "xstormy16_below100_operand" "") | |
1051 | (match_operand:QI 6 "register_operand" "")) | |
1052 | ] | |
1053 | "REGNO (operands[0]) == REGNO (operands[2]) | |
1054 | && REGNO (operands[0]) == REGNO (operands[3]) | |
1055 | && REGNO (operands[0]) == REGNO (operands[6]) | |
1056 | && rtx_equal_p (operands[1], operands[5])" | |
1057 | [(set (match_dup 1) | |
1058 | (ior:QI (match_dup 1) | |
1059 | (match_dup 4))) | |
1060 | ] | |
1061 | "") | |
1062 | ||
1063 | ||
1064 | (define_expand "andqi3" | |
1065 | [(match_operand:QI 0 "xstormy16_below100_or_register" "") | |
1066 | (match_operand:QI 1 "xstormy16_below100_or_register" "") | |
1067 | (match_operand:QI 2 "nonmemory_operand" "")] | |
1068 | "" | |
5ab9749e NC |
1069 | { |
1070 | xstormy16_expand_andqi3 (operands); | |
1071 | DONE; | |
1072 | }) | |
54e9a19d DD |
1073 | |
1074 | (define_insn "andqi3_internal" | |
1075 | [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr") | |
1076 | (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0") | |
1077 | (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))] | |
1078 | "" | |
1079 | "clr1 %0,%B2" | |
1080 | [(set_attr "length" "2") | |
1081 | (set_attr "psw_operand" "0")]) | |
1082 | ||
1083 | (define_peephole2 | |
1084 | [(set (match_operand:HI 0 "register_operand" "") | |
1085 | (and:HI (match_operand:HI 1 "register_operand" "") | |
1086 | (match_operand 2 "immediate_operand" ""))) | |
1087 | (set (match_operand:HI 3 "register_operand" "") | |
1088 | (zero_extend:HI (match_operand:QI 4 "register_operand" ""))); | |
1089 | ] | |
1090 | "REGNO (operands[0]) == REGNO (operands[1]) | |
1091 | && REGNO (operands[0]) == REGNO (operands[3]) | |
1092 | && REGNO (operands[0]) == REGNO (operands[4])" | |
1093 | [(set (match_dup 0) | |
1094 | (and:HI (match_dup 1) | |
1095 | (match_dup 5))) | |
1096 | ] | |
1097 | "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);") | |
1098 | ||
1099 | (define_peephole2 | |
1100 | [(set (match_operand:QI 0 "register_operand" "") | |
1101 | (match_operand:QI 1 "xstormy16_below100_operand" "")) | |
1102 | (set (match_operand:HI 2 "register_operand" "") | |
1103 | (and:HI (match_operand:HI 3 "register_operand" "") | |
1104 | (match_operand:QI 4 "xstormy16_onebit_clr_operand" ""))) | |
1105 | (set (match_operand:QI 5 "xstormy16_below100_operand" "") | |
1106 | (match_operand:QI 6 "register_operand" "")) | |
1107 | ] | |
1108 | "REGNO (operands[0]) == REGNO (operands[2]) | |
1109 | && REGNO (operands[0]) == REGNO (operands[3]) | |
1110 | && REGNO (operands[0]) == REGNO (operands[6]) | |
1111 | && rtx_equal_p (operands[1], operands[5])" | |
1112 | [(set (match_dup 1) | |
1113 | (and:QI (match_dup 1) | |
1114 | (match_dup 4))) | |
1115 | ] | |
1116 | "") | |
1117 | ||
1118 | ;; GCC uses different techniques to optimize MSB and LSB accesses, so | |
1119 | ;; we have to code those separately. | |
1120 | ||
1121 | (define_insn "*bclrx" | |
5ab9749e | 1122 | [(set (pc) |
54e9a19d DD |
1123 | (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W") |
1124 | (match_operand:HI 2 "immediate_operand" "i")) | |
1125 | (const_int 0)) | |
1126 | (label_ref (match_operand 0 "" "")) | |
1127 | (pc))) | |
d40ba0b6 | 1128 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1129 | "" |
1130 | "bn %1,%B2,%l0" | |
1131 | [(set_attr "length" "4") | |
1132 | (set_attr "psw_operand" "nop")]) | |
1133 | ||
1134 | (define_insn "*bclrx2" | |
5ab9749e | 1135 | [(set (pc) |
54e9a19d DD |
1136 | (if_then_else (zero_extract:HI |
1137 | (xor:HI (subreg:HI | |
1138 | (match_operand:QI 1 "xstormy16_below100_operand" "W") 0) | |
1139 | (match_operand:HI 2 "xstormy16_onebit_set_operand" "J")) | |
1140 | (const_int 1) | |
1141 | (match_operand:HI 3 "immediate_operand" "i")) | |
1142 | (label_ref (match_operand 0 "" "")) | |
1143 | (pc))) | |
d40ba0b6 | 1144 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1145 | "" |
1146 | "bn %1,%B2,%l0" | |
1147 | [(set_attr "length" "4") | |
1148 | (set_attr "psw_operand" "nop")]) | |
1149 | ||
f99652b5 | 1150 | (define_insn "*bclrx3" |
5ab9749e | 1151 | [(set (pc) |
f99652b5 NC |
1152 | (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")) |
1153 | (match_operand:HI 2 "immediate_operand" "i")) | |
1154 | (const_int 0)) | |
1155 | (label_ref (match_operand 0 "" "")) | |
1156 | (pc))) | |
d40ba0b6 | 1157 | (clobber (reg:BI CARRY_REG))] |
f99652b5 NC |
1158 | "" |
1159 | "bn %1,%B2,%l0" | |
1160 | [(set_attr "length" "4") | |
1161 | (set_attr "psw_operand" "nop")]) | |
1162 | ||
54e9a19d | 1163 | (define_insn "*bclr7" |
5ab9749e | 1164 | [(set (pc) |
54e9a19d DD |
1165 | (if_then_else (xor:HI (lshiftrt:HI (subreg:HI |
1166 | (match_operand:QI 1 "xstormy16_below100_operand" "W") 0) | |
1167 | (const_int 7)) | |
1168 | (const_int 1)) | |
1169 | (label_ref (match_operand 0 "" "")) | |
1170 | (pc))) | |
d40ba0b6 | 1171 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1172 | "" |
1173 | "bn %1,#7,%l0" | |
1174 | [(set_attr "length" "4") | |
1175 | (set_attr "psw_operand" "nop")]) | |
1176 | ||
1177 | (define_insn "*bclr15" | |
5ab9749e | 1178 | [(set (pc) |
54e9a19d DD |
1179 | (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")) |
1180 | (const_int 0)) | |
1181 | (label_ref (match_operand 0 "" "")) | |
1182 | (pc))) | |
d40ba0b6 | 1183 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1184 | "" |
1185 | "bn %1,#7,%l0" | |
1186 | [(set_attr "length" "4") | |
1187 | (set_attr "psw_operand" "nop")]) | |
1188 | ||
1189 | (define_insn "*bsetx" | |
5ab9749e | 1190 | [(set (pc) |
54e9a19d DD |
1191 | (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W") |
1192 | (match_operand:HI 2 "immediate_operand" "i")) | |
1193 | (const_int 0)) | |
1194 | (label_ref (match_operand 0 "" "")) | |
1195 | (pc))) | |
d40ba0b6 | 1196 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1197 | "" |
1198 | "bp %1,%B2,%l0" | |
1199 | [(set_attr "length" "4") | |
1200 | (set_attr "psw_operand" "nop")]) | |
1201 | ||
1202 | (define_insn "*bsetx2" | |
5ab9749e | 1203 | [(set (pc) |
54e9a19d DD |
1204 | (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") |
1205 | (const_int 1) | |
1206 | (match_operand:HI 2 "immediate_operand" "i")) | |
1207 | (label_ref (match_operand 0 "" "")) | |
1208 | (pc))) | |
d40ba0b6 | 1209 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1210 | "" |
1211 | "bp %1,%b2,%l0" | |
1212 | [(set_attr "length" "4") | |
1213 | (set_attr "psw_operand" "nop")]) | |
1214 | ||
f99652b5 | 1215 | (define_insn "*bsetx3" |
5ab9749e | 1216 | [(set (pc) |
f99652b5 NC |
1217 | (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")) |
1218 | (match_operand:HI 2 "immediate_operand" "i")) | |
1219 | (const_int 0)) | |
1220 | (label_ref (match_operand 0 "" "")) | |
1221 | (pc))) | |
d40ba0b6 | 1222 | (clobber (reg:BI CARRY_REG))] |
f99652b5 NC |
1223 | "" |
1224 | "bp %1,%B2,%l0" | |
1225 | [(set_attr "length" "4") | |
1226 | (set_attr "psw_operand" "nop")]) | |
1227 | ||
54e9a19d | 1228 | (define_insn "*bset7" |
5ab9749e | 1229 | [(set (pc) |
54e9a19d DD |
1230 | (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0) |
1231 | (const_int 7)) | |
1232 | (label_ref (match_operand 0 "" "")) | |
1233 | (pc))) | |
d40ba0b6 | 1234 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1235 | "" |
1236 | "bp %1,#7,%l0" | |
1237 | [(set_attr "length" "4") | |
1238 | (set_attr "psw_operand" "nop")]) | |
1239 | ||
1240 | (define_insn "*bset15" | |
5ab9749e | 1241 | [(set (pc) |
54e9a19d DD |
1242 | (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")) |
1243 | (const_int 0)) | |
1244 | (label_ref (match_operand 0 "" "")) | |
1245 | (pc))) | |
d40ba0b6 | 1246 | (clobber (reg:BI CARRY_REG))] |
54e9a19d DD |
1247 | "" |
1248 | "bp %1,#7,%l0" | |
1249 | [(set_attr "length" "4") | |
1250 | (set_attr "psw_operand" "nop")]) |