OSDN Git Service

* config/stormy16/stormy16.h (IRA_COVER_CLASSES): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / stormy16 / stormy16.md
1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2007, 2008
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,ie,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 4)
270               (const_int 8)])])
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 ; Note - the early clobber modifier is no longer needed on operand 3
308 ; and in fact can cause some reload spill failures if it is present.
309 ; Note that the 'Z' constraint matches "add $reg,0", which reload
310 ; will occasionally emit.  We avoid the "add $reg,imm" match because
311 ; it clobbers the carry.
312 (define_insn "addhi3"
313   [(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
314         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
315                  (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
316    (clobber (match_scratch:BI 3 "=X,X,X,y,y,y,y,y"))]
317   ""
318   "@
319    inc %0,%o2
320    dec %0,%O2
321    ;
322    add Rx,%2
323    sub Rx,#%n2
324    add %0,%2
325    sub %0,#%n2
326    add %0,%2"
327   [(set_attr "length" "2,2,0,2,2,2,2,4")])
328
329 ; Reload can generate addition operations.  The SECONDARY_RELOAD_CLASS
330 ; macro causes it to allocate the carry register; this pattern
331 ; shows it how to place the register in RTL to make the addition work.
332 (define_expand "reload_inhi"
333   [(parallel [(set (match_operand:HI 0 "register_operand" "=r")
334                    (match_operand:HI 1 "xstormy16_carry_plus_operand" ""))
335               (clobber (match_operand:BI 2 "" "=&y"))])]
336   ""
337   "if (! rtx_equal_p (operands[0], XEXP (operands[1], 0)))
338     {
339       emit_insn (gen_rtx_SET (VOIDmode, operands[0], XEXP (operands[1], 0)));
340       operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), operands[0],
341                                   XEXP (operands[1], 1));
342     }
343  ")
344
345 (define_insn "addchi4"
346   [(set (match_operand:HI 0 "register_operand" "=T,r,r")
347         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
348                  (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
349    (set (match_operand:BI 3 "register_operand" "=y,y,y")
350         (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
351                                            (zero_extend:SI (match_dup 2)))
352                                   (const_int 16))))]
353   ""
354   "@
355    add Rx,%2
356    add %0,%2
357    add %0,%2"
358   [(set_attr "length" "2,2,4")])
359
360 (define_insn "addchi5"
361   [(set (match_operand:HI 0 "register_operand" "=T,r,r")
362         (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
363                           (zero_extend:HI (match_operand:BI 3 
364                                                             "register_operand"
365                                                             "y,y,y")))
366                  (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
367    (set (match_operand:BI 4 "register_operand" "=y,y,y") 
368         (truncate:BI (lshiftrt:SI (plus:SI (plus:SI 
369                                             (zero_extend:SI (match_dup 1))
370                                             (zero_extend:SI (match_dup 3)))
371                                            (zero_extend:SI (match_dup 2)))
372                                   (const_int 16))))]
373   ""
374   "@
375    adc Rx,%2
376    adc %0,%2
377    adc %0,%2"
378   [(set_attr "length" "2,2,4")])
379
380 ;; Subtraction
381 ; Operand 3 is marked earlyclobber because that helps reload
382 ; to generate better code---this pattern will never need the
383 ; carry register as an input, and some output reloads or input
384 ; reloads might need to use it.  In fact, without the '&' reload
385 ; will fail in some cases.
386 (define_insn "subhi3"
387   [(set (match_operand:HI 0 "register_operand" "=r,r,T,T,r,r,r")
388         (minus:HI (match_operand:HI 1 "register_operand" "0,0,0,0,0,0,0")
389                   (match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,L,M,rI,M,i")))
390    (clobber (match_scratch:BI 3 "=X,X,&y,&y,&y,&y,&y"))]
391   ""
392   "@
393    dec %0,%o2
394    inc %0,%O2
395    sub Rx,%2
396    add Rx,#%n2
397    sub %0,%2
398    add %0,#%n2
399    sub %0,%2"
400   [(set_attr "length" "2,2,2,2,2,2,4")])
401
402 (define_insn "subchi4"
403   [(set (match_operand:HI 0 "register_operand" "=T,r,r")
404         (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
405                   (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
406    (set (match_operand:BI 3 "register_operand" "=y,y,y") 
407         (truncate:BI (lshiftrt:SI (minus:SI (zero_extend:SI (match_dup 1))
408                                             (zero_extend:SI (match_dup 2)))
409                                   (const_int 16))))]
410   ""
411   "@
412    sub Rx,%2
413    sub %0,%2
414    sub %0,%2"
415   [(set_attr "length" "2,2,4")])
416
417 (define_insn "subchi5"
418   [(set (match_operand:HI 0 "register_operand" "=T,r,r")
419         (minus:HI (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
420                           (zero_extend:HI (match_operand:BI 3 
421                                                             "register_operand"
422                                                             "y,y,y")))
423                  (match_operand:HI 2 "xs_hi_nonmemory_operand" "L,Ir,i")))
424    (set (match_operand:BI 4 "register_operand" "=y,y,y") 
425         (truncate:BI (lshiftrt:SI (minus:SI (minus:SI 
426                                              (zero_extend:SI (match_dup 1))
427                                              (zero_extend:SI (match_dup 3)))
428                                             (zero_extend:SI (match_dup 2)))
429                                   (const_int 16))))]
430   ""
431   "@
432    sbc Rx,%2
433    sbc %0,%2
434    sbc %0,%2"
435   [(set_attr "length" "2,2,4")])
436
437 ; Basic multiplication
438 (define_insn "mulhi3"
439   [(set (match_operand:HI 0 "register_operand" "=a")
440         (mult:HI (match_operand:HI 1 "register_operand" "%a")
441                  (match_operand:HI 2 "register_operand" "c")))
442    (clobber (match_scratch:HI 3 "=b"))
443    ]
444   ""
445   "mul"
446   [(set_attr "psw_operand" "nop")])
447
448 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
449 ; The constraint on operand 0 is 't' because it is actually two regs
450 ; long, and both regs must match the constraint.
451 (define_insn "umulhisi3"
452   [(set (match_operand:SI 0 "register_operand" "=t")
453         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%a"))
454                  (zero_extend:SI (match_operand:HI 2 "register_operand" "c"))))
455    ]
456   ""
457   "mul"
458   [(set_attr "psw_operand" "nop")])
459
460 ;; Unsigned division giving both quotient and remainder
461 (define_insn "udivmodhi4"
462   [(set (match_operand:HI 0 "register_operand" "=a")
463         (udiv:HI (match_operand:HI 1 "register_operand" "a")
464                  (match_operand:HI 2 "register_operand" "c")))
465    (set (match_operand:HI 3 "register_operand" "=b")
466         (umod:HI (match_dup 1)
467                  (match_dup 2)))]
468   ""
469   "div"
470   [(set_attr "psw_operand" "nop")])
471
472 ;; Signed division giving both quotient and remainder
473 (define_insn "divmodhi4"
474   [(set (match_operand:HI 0 "register_operand" "=a")
475         (div:HI (match_operand:HI 1 "register_operand" "a")
476                  (match_operand:HI 2 "register_operand" "c")))
477    (set (match_operand:HI 3 "register_operand" "=b")
478         (mod:HI (match_dup 1)
479                  (match_dup 2)))]
480   ""
481   "sdiv"
482   [(set_attr "psw_operand" "nop")])
483
484 ;; Signed 32/16 division
485 (define_insn "sdivlh"
486   [(set (match_operand:HI 0 "register_operand" "=a")
487         (div:HI (match_operand:SI 2 "register_operand" "t")
488                  (match_operand:HI 3 "register_operand" "c")))
489    (set (match_operand:HI 1 "register_operand" "=b")
490         (mod:HI (match_dup 2)
491                  (match_dup 3)))]
492   ""
493   "sdivlh"
494   [(set_attr "psw_operand" "nop")])
495
496 ;; Unsigned 32/16 division
497 (define_insn "udivlh"
498   [(set (match_operand:HI 0 "register_operand" "=a")
499         (udiv:HI (match_operand:SI 2 "register_operand" "t")
500                  (match_operand:HI 3 "register_operand" "c")))
501    (set (match_operand:HI 1 "register_operand" "=b")
502         (umod:HI (match_dup 2)
503                  (match_dup 3)))]
504   ""
505   "divlh"
506   [(set_attr "psw_operand" "nop")])
507
508 ;; Negation
509
510 (define_expand "neghi2"
511   [(set (match_operand:HI 0 "register_operand" "")
512         (not:HI (match_operand:HI 1 "register_operand" "")))
513    (parallel [(set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
514               (clobber (match_scratch:BI 3 ""))])]
515   ""
516   "")
517
518 \f
519 ;; ::::::::::::::::::::
520 ;; ::
521 ;; :: 16-bit Integer Shifts and Rotates
522 ;; ::
523 ;; ::::::::::::::::::::
524
525 ;; Arithmetic Shift Left
526 (define_insn "ashlhi3"
527   [(set (match_operand:HI 0 "register_operand" "=r")
528         (ashift:HI (match_operand:HI 1 "register_operand" "0")
529                    (match_operand:HI 2 "nonmemory_operand" "ri")))
530    (clobber (match_scratch:BI 3 "=y"))]
531   ""
532   "shl %0,%2")
533
534 ;; Arithmetic Shift Right
535 (define_insn "ashrhi3"
536   [(set (match_operand:HI 0 "register_operand" "=r")
537         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
538                      (match_operand:HI 2 "nonmemory_operand" "ri")))
539    (clobber (match_scratch:BI 3 "=y"))]
540   ""
541   "asr %0,%2")
542
543 ;; Logical Shift Right
544 (define_insn "lshrhi3"
545   [(set (match_operand:HI 0 "register_operand" "=r")
546         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
547                      (match_operand:HI 2 "nonmemory_operand" "ri")))
548    (clobber (match_scratch:BI 3 "=y"))]
549   ""
550   "shr %0,%2")
551
552 \f
553 ;; ::::::::::::::::::::
554 ;; ::
555 ;; :: 16-Bit Integer Logical operations
556 ;; ::
557 ;; ::::::::::::::::::::
558
559 ;; Logical AND, 16-bit integers
560 (define_insn "andhi3"
561   [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
562         (and:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
563                 (match_operand:HI 2 "nonmemory_operand" "L,r,K,i,K")))]
564   ""
565   "@
566    and Rx,%2
567    and %0,%2
568    clr1 %0,%B2
569    and %0,%2
570    #"
571   [(set_attr "length" "2,2,2,4,2")])
572
573 (define_split
574   [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
575         (and:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
576                 (match_operand:HI 2 "xstormy16_onebit_clr_operand" "")))]
577   ""
578   [(set (match_dup 3)
579         (and:QI (match_dup 4)
580                 (match_dup 5)))]
581   "{ int s = ((INTVAL (operands[2]) & 0xff) == 0xff) ? 1 : 0;
582      operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
583      operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
584      operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
585      operands[5] = GEN_INT (INTVAL (operands[5]) | ~(HOST_WIDE_INT)0xff);
586    }
587 ")
588
589 ;; Inclusive OR, 16-bit integers
590 (define_insn "iorhi3"
591   [(set (match_operand:HI 0 "xstormy16_splittable_below100_or_register" "=T,r,r,r,W")
592         (ior:HI (match_operand:HI 1 "xstormy16_below100_or_register" "%0,0,0,0,0")
593                 (match_operand:HI 2 "nonmemory_operand" "L,r,J,i,J")))]
594   ""
595   "@
596    or Rx,%2
597    or %0,%2
598    set1 %0,%B2
599    or %0,%2
600    #"
601   [(set_attr "length" "2,2,2,4,2")])
602
603 (define_split
604   [(set (match_operand:HI 0 "xstormy16_below100_operand" "")
605         (ior:HI (match_operand:HI 1 "xstormy16_below100_operand" "")
606                 (match_operand:HI 2 "xstormy16_onebit_set_operand" "")))]
607   ""
608   [(set (match_dup 3)
609         (ior:QI (match_dup 4)
610                 (match_dup 5)))]
611   "{ int s = ((INTVAL (operands[2]) & 0xff) == 0x00) ? 1 : 0;
612      operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, s);
613      operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, s);
614      operands[5] = simplify_gen_subreg (QImode, operands[2], HImode, s);
615      operands[5] = GEN_INT (INTVAL (operands[5]) & 0xff);
616    }
617 ")
618
619 ;; Exclusive OR, 16-bit integers
620 (define_insn "xorhi3"
621   [(set (match_operand:HI 0 "register_operand" "=T,r,r")
622         (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0")
623                 (match_operand:HI 2 "nonmemory_operand" "L,r,i")))]
624   ""
625   "@
626    xor Rx,%2
627    xor %0,%2
628    xor %0,%2"
629   [(set_attr "length" "2,2,4")])
630
631 ;; One's complement, 16-bit integers
632 (define_insn "one_cmplhi2"
633   [(set (match_operand:HI 0 "register_operand" "=r")
634         (not:HI (match_operand:HI 1 "register_operand" "0")))]
635   ""
636   "not %0")
637
638 \f
639 ;; ::::::::::::::::::::
640 ;; ::
641 ;; :: 32-bit Integer arithmetic
642 ;; ::
643 ;; ::::::::::::::::::::
644
645 ;; Addition
646 (define_insn_and_split "addsi3"
647   [(set (match_operand:SI 0 "register_operand" "=r")
648         (plus:SI (match_operand:SI 1 "register_operand" "%0")
649                  (match_operand:SI 2 "nonmemory_operand" "ri")))
650    (clobber (match_scratch:BI 3 "=y"))]
651   ""
652   "#"
653   "reload_completed"
654   [(pc)]
655   "{ xstormy16_expand_arith (SImode, PLUS, operands[0], operands[1],
656                             operands[2], operands[3]); DONE; } "
657   [(set_attr "length" "4")])
658
659 ;; Subtraction
660 (define_insn_and_split "subsi3"
661   [(set (match_operand:SI 0 "register_operand" "=r")
662         (minus:SI (match_operand:SI 1 "register_operand" "0")
663                  (match_operand:SI 2 "nonmemory_operand" "ri")))
664    (clobber (match_scratch:BI 3 "=y"))]
665   ""
666   "#"
667   "reload_completed"
668   [(pc)]
669   "{ xstormy16_expand_arith (SImode, MINUS, operands[0], operands[1],
670                             operands[2], operands[3]); DONE; } "
671   [(set_attr "length" "4")])
672
673 (define_expand "negsi2"
674   [(parallel [(set (match_operand:SI 0 "register_operand" "")
675                    (neg:SI (match_operand:SI 1 "register_operand" "")))
676               (clobber (match_scratch:BI 2 ""))])]
677   ""
678   "{ operands[2] = gen_reg_rtx (HImode);
679      operands[3] = gen_reg_rtx (BImode); }")
680
681 (define_insn_and_split "*negsi2_internal"
682   [(set (match_operand:SI 0 "register_operand" "=&r")
683         (neg:SI (match_operand:SI 1 "register_operand" "r")))
684    (clobber (match_scratch:BI 2 "=y"))]
685   ""
686   "#"
687   "reload_completed"
688   [(pc)]
689   "{ xstormy16_expand_arith (SImode, NEG, operands[0], operands[0],
690                             operands[1], operands[2]); DONE; }")
691
692 ;; ::::::::::::::::::::
693 ;; ::
694 ;; :: 32-bit Integer Shifts and Rotates
695 ;; ::
696 ;; ::::::::::::::::::::
697
698 ;; Arithmetic Shift Left
699 (define_expand "ashlsi3"
700   [(parallel [(set (match_operand:SI 0 "register_operand" "")
701                    (ashift:SI (match_operand:SI 1 "register_operand" "")
702                               (match_operand:SI 2 "const_int_operand" "")))
703               (clobber (match_dup 3))
704               (clobber (match_dup 4))])]
705   ""
706   " if (! const_int_operand (operands[2], SImode)) FAIL;
707   operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
708
709 ;; Arithmetic Shift Right
710 (define_expand "ashrsi3"
711   [(parallel [(set (match_operand:SI 0 "register_operand" "")
712                    (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
713                                 (match_operand:SI 2 "const_int_operand" "")))
714               (clobber (match_dup 3))
715               (clobber (match_dup 4))])]
716   ""
717   " if (! const_int_operand (operands[2], SImode)) FAIL;
718   operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
719
720 ;; Logical Shift Right
721 (define_expand "lshrsi3"
722   [(parallel [(set (match_operand:SI 0 "register_operand" "")
723                    (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
724                                 (match_operand:SI 2 "const_int_operand" "")))
725               (clobber (match_dup 3))
726               (clobber (match_dup 4))])]
727   ""
728   " if (! const_int_operand (operands[2], SImode)) FAIL;
729   operands[3] = gen_reg_rtx (BImode); operands[4] = gen_reg_rtx (HImode); ")
730
731 (define_insn "*shiftsi"
732   [(set (match_operand:SI 0 "register_operand" "=r,r")
733         (match_operator:SI 5 "shift_operator"
734          [(match_operand:SI 1 "register_operand" "0,0")
735           (match_operand:SI 2 "const_int_operand" "U,n")]))
736    (clobber (match_operand:BI 3 "register_operand" "=y,y"))
737    (clobber (match_operand:HI 4 "" "=X,r"))]
738   ""
739   "* return xstormy16_output_shift (SImode, GET_CODE (operands[5]), 
740                                    operands[0], operands[2], operands[4]);"
741   [(set_attr "length" "6,10")
742    (set_attr "psw_operand" "clobber,clobber")])
743
744 \f
745 ;; ::::::::::::::::::::
746 ;; ::
747 ;; :: Comparisons
748 ;; ::
749 ;; ::::::::::::::::::::
750
751 ;; Note, we store the operands in the comparison insns, and use them later
752 ;; when generating the branch or scc operation.
753
754 ;; First the routines called by the machine independent part of the compiler
755 (define_expand "cmphi"
756   [(set (cc0)
757         (compare (match_operand:HI 0 "register_operand" "")
758                  (match_operand:HI 1 "nonmemory_operand" "")))]
759   ""
760   "
761 {
762   xstormy16_compare_op0 = operands[0];
763   xstormy16_compare_op1 = operands[1];
764   DONE;
765 }")
766
767 ; There are no real SImode comparisons, but some can be emulated
768 ; by performing a SImode subtract and looking at the condition flags.
769 (define_expand "cmpsi"
770   [(set (cc0)
771         (compare (match_operand:SI 0 "register_operand" "")
772                  (match_operand:SI 1 "nonmemory_operand" "")))]
773   ""
774   "
775 {
776   xstormy16_compare_op0 = operands[0];
777   xstormy16_compare_op1 = operands[1];
778   DONE;
779 }")
780
781 \f
782 ;; ::::::::::::::::::::
783 ;; ::
784 ;; :: Branches
785 ;; ::
786 ;; ::::::::::::::::::::
787
788 (define_expand "beq"
789   [(use (match_operand 0 "" ""))]
790   ""
791   "{ xstormy16_emit_cbranch (EQ, operands[0]); DONE; }")
792
793 (define_expand "bne"
794   [(use (match_operand 0 "" ""))]
795   ""
796   "{ xstormy16_emit_cbranch (NE, operands[0]); DONE; }")
797
798 (define_expand "bge"
799   [(use (match_operand 0 "" ""))]
800   ""
801   "{ xstormy16_emit_cbranch (GE, operands[0]); DONE; }")
802
803 (define_expand "bgt"
804   [(use (match_operand 0 "" ""))]
805   ""
806   "{ xstormy16_emit_cbranch (GT, operands[0]); DONE; }")
807
808 (define_expand "ble"
809   [(use (match_operand 0 "" ""))]
810   ""
811   "{ xstormy16_emit_cbranch (LE, operands[0]); DONE; }")
812
813 (define_expand "blt"
814   [(use (match_operand 0 "" ""))]
815   ""
816   "{ xstormy16_emit_cbranch (LT, operands[0]); DONE; }")
817
818 (define_expand "bgeu"
819   [(use (match_operand 0 "" ""))]
820   ""
821   "{ xstormy16_emit_cbranch (GEU, operands[0]); DONE; }")
822
823 (define_expand "bgtu"
824   [(use (match_operand 0 "" ""))]
825   ""
826   "{ xstormy16_emit_cbranch (GTU, operands[0]); DONE; }")
827
828 (define_expand "bleu"
829   [(use (match_operand 0 "" ""))]
830   ""
831   "{ xstormy16_emit_cbranch (LEU, operands[0]); DONE; }")
832
833 (define_expand "bltu"
834   [(use (match_operand 0 "" ""))]
835   ""
836   "{ xstormy16_emit_cbranch (LTU, operands[0]); DONE; }")
837
838
839 (define_insn "cbranchhi"
840   [(set (pc) 
841         (if_then_else (match_operator:HI 1 "comparison_operator"
842                                       [(match_operand:HI 2 "nonmemory_operand" 
843                                         "r,e,L")
844                                        (match_operand:HI 3 "nonmemory_operand"
845                                                       "r,L,e")])
846                       (label_ref (match_operand 0 "" ""))
847                       (pc)))
848    (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
849   ""
850   "*
851 {
852   return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 0, insn);
853 }"
854   [(set_attr "branch_class" "bcc12")
855    (set_attr "psw_operand" "0,0,1")])
856
857 (define_insn "cbranchhi_neg"
858   [(set (pc) 
859         (if_then_else (match_operator:HI 1 "comparison_operator"
860                                       [(match_operand:HI 2 "nonmemory_operand" 
861                                                          "r,e,L")
862                                        (match_operand:HI 3 "nonmemory_operand"
863                                                          "r,L,e")])
864                       (pc)
865                       (label_ref (match_operand 0 "" ""))))
866    (clobber (match_operand:BI 4 "" "=&y,&y,&y"))]
867   ""
868   "*
869 {
870   return xstormy16_output_cbranch_hi (operands[1], \"%l0\", 1, insn);
871 }"
872   [(set_attr "branch_class" "bcc12")
873    (set_attr "psw_operand" "0,0,1")])
874
875 (define_insn "*eqbranchsi"
876   [(set (pc)
877         (if_then_else (match_operator:SI 1 "equality_operator"
878                                       [(match_operand:SI 2 "register_operand" 
879                                                          "r")
880                                        (const_int 0)])
881                       (label_ref (match_operand 0 "" ""))
882                       (pc)))
883    (clobber (match_operand:SI 3 "register_operand" "=2"))]
884   ""
885   "*
886 {
887   return xstormy16_output_cbranch_si (operands[1], \"%l0\", 0, insn);
888 }"
889   [(set_attr "branch_class" "bcc8p2")
890    (set_attr "psw_operand" "clobber")])
891
892 (define_insn_and_split "*ineqbranchsi"
893   [(set (pc)
894         (if_then_else (match_operator:SI 1 "xstormy16_ineqsi_operator"
895                                       [(match_operand:SI 2 "register_operand" 
896                                                          "r")
897                                        (match_operand:SI 3 "nonmemory_operand" 
898                                                          "ri")])
899                       (label_ref (match_operand 0 "" ""))
900                       (pc)))
901    (clobber (match_operand:SI 5 "register_operand" "=2"))
902    (clobber (match_operand:BI 4 "" "=&y"))]
903   ""
904   "#"
905   "reload_completed"
906   [(pc)]
907   "{ xstormy16_split_cbranch (SImode, operands[0], operands[1], operands[2],
908                              operands[4]); DONE; }"
909   [(set_attr "length" "8")])
910
911 (define_insn "*ineqbranch_1"
912   [(set (pc)
913         (if_then_else (match_operator:HI 5 "xstormy16_ineqsi_operator"
914                        [(minus:HI (match_operand:HI 1 "register_operand" 
915                                                     "T,r,r")
916                            (zero_extend:HI (match_operand:BI 4
917                                                              "register_operand"
918                                                              "y,y,y")))
919                         (match_operand:HI 3 "nonmemory_operand" "L,Ir,i")])
920                       (label_ref (match_operand 0 "" ""))
921                       (pc)))
922    (set (match_operand:HI 2 "register_operand" "=1,1,1")
923         (minus:HI (minus:HI (match_dup 1) (zero_extend:HI (match_dup 4)))
924                   (match_dup 3)))
925    (clobber (match_operand:BI 6 "" "=y,y,y"))]
926   ""
927   "*
928 {
929   return xstormy16_output_cbranch_si (operands[5], \"%l0\", 0, insn);
930 }"
931   [(set_attr "branch_class" "bcc8p2,bcc8p2,bcc8p4")
932    (set_attr "psw_operand" "2,2,2")])
933
934 \f
935 ;; ::::::::::::::::::::
936 ;; ::
937 ;; :: Call and branch instructions
938 ;; ::
939 ;; ::::::::::::::::::::
940
941 ;; Subroutine call instruction returning no value.  Operand 0 is the function
942 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
943 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
944 ;; registers used as operands.
945
946 ;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
947 ;; is supplied for the sake of some RISC machines which need to put this
948 ;; information into the assembler code; they can put it in the RTL instead of
949 ;; operand 1.
950
951 (define_expand "call"
952   [(call (match_operand:HI 0 "memory_operand" "m")
953          (match_operand 1 "" ""))
954    (use (match_operand 2 "immediate_operand" ""))]
955   ""
956   "xstormy16_expand_call (NULL_RTX, operands[0], operands[1]); DONE;")
957
958 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
959 ;; register in which the value is returned.  There are three more operands, the
960 ;; same as the three operands of the `call' instruction (but with numbers
961 ;; increased by one).
962
963 ;; Subroutines that return `BLKmode' objects use the `call' insn.
964
965 (define_expand "call_value"
966   [(set (match_operand 0 "register_operand" "=r")
967         (call (match_operand:HI 1 "memory_operand" "m")
968               (match_operand:SI 2 "" "")))
969         (use (match_operand 3 "immediate_operand" ""))]
970   ""
971   "xstormy16_expand_call (operands[0], operands[1], operands[2]); DONE;")
972
973 (define_insn "*call_internal"
974   [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
975          (match_operand 1 "" ""))
976    (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
977   ""
978   "@
979    callf %C0
980    call %2,%0"
981   [(set_attr "length" "4,2")
982    (set_attr "psw_operand" "clobber")])
983
984 (define_insn "*call_value_internal"
985   [(set (match_operand 3 "register_operand" "=r,r")
986         (call (mem:HI (match_operand:HI 0 "nonmemory_operand" "i,r"))
987               (match_operand 1 "" "")))
988    (use (match_operand:HI 2 "nonmemory_operand" "X,z"))]
989   ""
990   "@
991    callf %C0
992    call %2,%0"
993   [(set_attr "length" "4,2")
994    (set_attr "psw_operand" "clobber")])
995
996 ;; Subroutine return
997 (define_expand "return"
998   [(return)]
999   "direct_return()"
1000   "")
1001
1002 (define_insn "return_internal"
1003   [(return)]
1004   ""
1005   "ret"
1006   [(set_attr "psw_operand" "nop")])
1007
1008 (define_insn "return_internal_interrupt"
1009   [(return)
1010    (unspec_volatile [(const_int 0)] 1)]
1011   ""
1012   "iret"
1013   [(set_attr "psw_operand" "clobber")])
1014
1015 ;; Normal unconditional jump
1016 (define_insn "jump"
1017   [(set (pc) (label_ref (match_operand 0 "" "")))]
1018   ""
1019   "*
1020 {
1021   return xstormy16_output_cbranch_hi (NULL_RTX, \"%l0\", 0, insn);
1022 }"
1023   [(set_attr "branch_class" "br12")
1024    (set_attr "psw_operand" "nop")])
1025
1026 ;; Indirect jump through a register
1027 (define_expand "indirect_jump"
1028   [(set (match_dup 1) (const_int 0))
1029    (parallel [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1030               (use (match_dup 1))])]
1031   ""
1032   "operands[1] = gen_reg_rtx (HImode);")
1033
1034 (define_insn ""
1035   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1036    (use (match_operand:HI 1 "register_operand" "z"))]
1037   ""
1038   "jmp %1,%0"
1039   [(set_attr "length" "4")
1040    (set_attr "psw_operand" "nop")])
1041
1042 ;; Table-based switch statements.
1043 (define_expand "casesi"
1044   [(use (match_operand:SI 0 "register_operand" ""))
1045    (use (match_operand:SI 1 "immediate_operand" ""))
1046    (use (match_operand:SI 2 "immediate_operand" ""))
1047    (use (label_ref (match_operand 3 "" "")))
1048    (use (label_ref (match_operand 4 "" "")))]
1049   ""
1050   "
1051 {
1052   xstormy16_expand_casesi (operands[0], operands[1], operands[2],
1053                           operands[3], operands[4]);
1054   DONE;
1055 }")
1056
1057 (define_insn "tablejump_pcrel"
1058   [(set (pc) (mem:HI (plus:HI (pc) 
1059                               (match_operand:HI 0 "register_operand" "r"))))
1060    (use (label_ref:SI (match_operand 1 "" "")))]
1061   ""
1062   "br %0"
1063   [(set_attr "psw_operand" "nop")])
1064
1065 \f
1066 ;; ::::::::::::::::::::
1067 ;; ::
1068 ;; :: Prologue and Epilogue instructions
1069 ;; ::
1070 ;; ::::::::::::::::::::
1071
1072 ;; Called after register allocation to add any instructions needed for
1073 ;; the prologue.  Using a prologue insn is favored compared to putting
1074 ;; all of the instructions in the TARGET_ASM_FUNCTION_PROLOGUE macro,
1075 ;; since it allows the scheduler to intermix instructions with the
1076 ;; saves of the caller saved registers.  In some cases, it might be
1077 ;; necessary to emit a barrier instruction as the last insn to prevent
1078 ;; such scheduling.
1079 (define_expand "prologue"
1080   [(const_int 1)]
1081   ""
1082   "
1083 {
1084   xstormy16_expand_prologue ();
1085   DONE;
1086 }")
1087
1088 ;; Called after register allocation to add any instructions needed for
1089 ;; the epilogue.  Using an epilogue insn is favored compared to putting
1090 ;; all of the instructions in the TARGET_ASM_FUNCTION_EPILOGUE macro,
1091 ;; since it allows the scheduler to intermix instructions with the
1092 ;; restores of the caller saved registers.  In some cases, it might be
1093 ;; necessary to emit a barrier instruction as the first insn to
1094 ;; prevent such scheduling.
1095 (define_expand "epilogue"
1096   [(const_int 2)]
1097   ""
1098   "
1099 {
1100   xstormy16_expand_epilogue ();
1101   DONE;
1102 }")
1103
1104 \f
1105 ;; ::::::::::::::::::::
1106 ;; ::
1107 ;; :: Miscellaneous instructions
1108 ;; ::
1109 ;; ::::::::::::::::::::
1110
1111 ;; No operation, needed in case the user uses -g but not -O.
1112 (define_insn "nop"
1113   [(const_int 0)]
1114   ""
1115   "nop"
1116   [(set_attr "psw_operand" "nop")])
1117
1118 ;; Pseudo instruction that prevents the scheduler from moving code above this
1119 ;; point.
1120 (define_insn "blockage"
1121   [(unspec_volatile [(const_int 0)] 0)]
1122   ""
1123   ""
1124   [(set_attr "length" "0")
1125    (set_attr "psw_operand" "nop")])
1126
1127 ;;---------------------------------------------------------------------------
1128
1129 (define_expand "iorqi3"
1130   [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1131    (match_operand:QI 1 "xstormy16_below100_or_register" "")
1132    (match_operand:QI 2 "nonmemory_operand" "")]
1133   ""
1134   "
1135 {
1136   xstormy16_expand_iorqi3 (operands);
1137   DONE;
1138 }")
1139
1140 (define_insn "iorqi3_internal"
1141   [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1142         (ior:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1143                 (match_operand:QI 2 "xstormy16_onebit_set_operand" "i")))]
1144   ""
1145   "set1 %0,%B2"
1146   [(set_attr "length" "2")
1147    (set_attr "psw_operand" "0")])
1148
1149 (define_peephole2
1150   [(set (match_operand:QI 0 "register_operand" "")
1151         (match_operand:QI 1 "xstormy16_below100_operand" ""))
1152    (set (match_operand:HI 2 "register_operand" "")
1153         (ior:HI (match_operand:HI 3 "register_operand" "")
1154                 (match_operand:QI 4 "xstormy16_onebit_set_operand" "")))
1155    (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1156         (match_operand:QI 6 "register_operand" ""))
1157    ]
1158   "REGNO (operands[0]) == REGNO (operands[2])
1159    && REGNO (operands[0]) == REGNO (operands[3])
1160    && REGNO (operands[0]) == REGNO (operands[6])
1161    && rtx_equal_p (operands[1], operands[5])"
1162   [(set (match_dup 1)
1163         (ior:QI (match_dup 1)
1164                 (match_dup 4)))
1165    ]
1166   "")
1167
1168
1169 (define_expand "andqi3"
1170   [(match_operand:QI 0 "xstormy16_below100_or_register" "")
1171    (match_operand:QI 1 "xstormy16_below100_or_register" "")
1172    (match_operand:QI 2 "nonmemory_operand" "")]
1173   ""
1174   "
1175 {
1176   xstormy16_expand_andqi3 (operands);
1177   DONE;
1178 }")
1179
1180 (define_insn "andqi3_internal"
1181   [(set (match_operand:QI 0 "xstormy16_below100_or_register" "=Wr")
1182         (and:QI (match_operand:QI 1 "xstormy16_below100_or_register" "0")
1183                 (match_operand:QI 2 "xstormy16_onebit_clr_operand" "i")))]
1184   ""
1185   "clr1 %0,%B2"
1186   [(set_attr "length" "2")
1187    (set_attr "psw_operand" "0")])
1188
1189 (define_peephole2
1190   [(set (match_operand:HI 0 "register_operand" "")
1191         (and:HI (match_operand:HI 1 "register_operand" "")
1192                 (match_operand 2 "immediate_operand" "")))
1193    (set (match_operand:HI 3 "register_operand" "")
1194         (zero_extend:HI (match_operand:QI 4 "register_operand" "")));
1195    ]
1196   "REGNO (operands[0]) == REGNO (operands[1])
1197    && REGNO (operands[0]) == REGNO (operands[3])
1198    && REGNO (operands[0]) == REGNO (operands[4])"
1199   [(set (match_dup 0)
1200         (and:HI (match_dup 1)
1201                 (match_dup 5)))
1202    ]
1203   "operands[5] = GEN_INT (INTVAL (operands[2]) & 0xff);")
1204
1205 (define_peephole2
1206   [(set (match_operand:QI 0 "register_operand" "")
1207         (match_operand:QI 1 "xstormy16_below100_operand" ""))
1208    (set (match_operand:HI 2 "register_operand" "")
1209         (and:HI (match_operand:HI 3 "register_operand" "")
1210                 (match_operand:QI 4 "xstormy16_onebit_clr_operand" "")))
1211    (set (match_operand:QI 5 "xstormy16_below100_operand" "")
1212         (match_operand:QI 6 "register_operand" ""))
1213    ]
1214   "REGNO (operands[0]) == REGNO (operands[2])
1215    && REGNO (operands[0]) == REGNO (operands[3])
1216    && REGNO (operands[0]) == REGNO (operands[6])
1217    && rtx_equal_p (operands[1], operands[5])"
1218   [(set (match_dup 1)
1219         (and:QI (match_dup 1)
1220                 (match_dup 4)))
1221    ]
1222   "")
1223
1224 ;; GCC uses different techniques to optimize MSB and LSB accesses, so
1225 ;; we have to code those separately.
1226
1227 (define_insn "*bclrx"
1228   [(set (pc) 
1229         (if_then_else (eq:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1230                                      (match_operand:HI 2 "immediate_operand" "i"))
1231                              (const_int 0))
1232                       (label_ref (match_operand 0 "" ""))
1233                       (pc)))
1234    (clobber (match_operand:BI 3 "" "=y"))]
1235   ""
1236   "bn %1,%B2,%l0"
1237   [(set_attr "length" "4")
1238    (set_attr "psw_operand" "nop")])
1239
1240 (define_insn "*bclrx2"
1241   [(set (pc) 
1242         (if_then_else (zero_extract:HI
1243                        (xor:HI (subreg:HI
1244                                 (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1245                                (match_operand:HI 2 "xstormy16_onebit_set_operand" "J"))
1246                        (const_int 1)
1247                        (match_operand:HI 3 "immediate_operand" "i"))
1248                       (label_ref (match_operand 0 "" ""))
1249                       (pc)))
1250    (clobber (match_operand:BI 4 "" "=y"))]
1251   ""
1252   "bn %1,%B2,%l0"
1253   [(set_attr "length" "4")
1254    (set_attr "psw_operand" "nop")])
1255
1256 (define_insn "*bclrx3"
1257   [(set (pc) 
1258         (if_then_else (eq:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1259                                      (match_operand:HI 2 "immediate_operand" "i"))
1260                              (const_int 0))
1261                       (label_ref (match_operand 0 "" ""))
1262                       (pc)))
1263    (clobber (match_operand:BI 3 "" "=y"))]
1264   ""
1265   "bn %1,%B2,%l0"
1266   [(set_attr "length" "4")
1267    (set_attr "psw_operand" "nop")])
1268
1269 (define_insn "*bclr7"
1270   [(set (pc) 
1271         (if_then_else (xor:HI (lshiftrt:HI (subreg:HI
1272                                             (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1273                                            (const_int 7))
1274                               (const_int 1))
1275                       (label_ref (match_operand 0 "" ""))
1276                       (pc)))
1277    (clobber (match_operand:BI 2 "" "=y"))]
1278   ""
1279   "bn %1,#7,%l0"
1280   [(set_attr "length" "4")
1281    (set_attr "psw_operand" "nop")])
1282
1283 (define_insn "*bclr15"
1284   [(set (pc) 
1285         (if_then_else (ge:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1286                              (const_int 0))
1287                       (label_ref (match_operand 0 "" ""))
1288                       (pc)))
1289    (clobber (match_operand:BI 2 "" "=y"))]
1290   ""
1291   "bn %1,#7,%l0"
1292   [(set_attr "length" "4")
1293    (set_attr "psw_operand" "nop")])
1294
1295 (define_insn "*bsetx"
1296   [(set (pc) 
1297         (if_then_else (ne:HI (and:QI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1298                                      (match_operand:HI 2 "immediate_operand" "i"))
1299                              (const_int 0))
1300                       (label_ref (match_operand 0 "" ""))
1301                       (pc)))
1302    (clobber (match_operand:BI 3 "" "=y"))]
1303   ""
1304   "bp %1,%B2,%l0"
1305   [(set_attr "length" "4")
1306    (set_attr "psw_operand" "nop")])
1307
1308 (define_insn "*bsetx2"
1309   [(set (pc) 
1310         (if_then_else (zero_extract:HI (match_operand:QI 1 "xstormy16_below100_operand" "W")
1311                                        (const_int 1)
1312                                        (match_operand:HI 2 "immediate_operand" "i"))
1313                       (label_ref (match_operand 0 "" ""))
1314                       (pc)))
1315    (clobber (match_operand:BI 3 "" "=y"))]
1316   ""
1317   "bp %1,%b2,%l0"
1318   [(set_attr "length" "4")
1319    (set_attr "psw_operand" "nop")])
1320
1321 (define_insn "*bsetx3"
1322   [(set (pc) 
1323         (if_then_else (ne:HI (and:HI (zero_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1324                                      (match_operand:HI 2 "immediate_operand" "i"))
1325                              (const_int 0))
1326                       (label_ref (match_operand 0 "" ""))
1327                       (pc)))
1328    (clobber (match_operand:BI 3 "" "=y"))]
1329   ""
1330   "bp %1,%B2,%l0"
1331   [(set_attr "length" "4")
1332    (set_attr "psw_operand" "nop")])
1333
1334 (define_insn "*bset7"
1335   [(set (pc) 
1336         (if_then_else (lshiftrt:HI (subreg:HI (match_operand:QI 1 "xstormy16_below100_operand" "W") 0)
1337                                    (const_int 7))
1338                       (label_ref (match_operand 0 "" ""))
1339                       (pc)))
1340    (clobber (match_operand:BI 2 "" "=y"))]
1341   ""
1342   "bp %1,#7,%l0"
1343   [(set_attr "length" "4")
1344    (set_attr "psw_operand" "nop")])
1345
1346 (define_insn "*bset15"
1347   [(set (pc) 
1348         (if_then_else (lt:HI (sign_extend:HI (match_operand:QI 1 "xstormy16_below100_operand" "W"))
1349                              (const_int 0))
1350                       (label_ref (match_operand 0 "" ""))
1351                       (pc)))
1352    (clobber (match_operand:BI 2 "" "=y"))]
1353   ""
1354   "bp %1,#7,%l0"
1355   [(set_attr "length" "4")
1356    (set_attr "psw_operand" "nop")])