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