OSDN Git Service

config/stormy16/stormy16.c (combine_bnp): Add code to handle zero_extension and
[pf3gnuchains/gcc-fork.git] / gcc / config / stormy16 / stormy16.md
1 ;; XSTORMY16 Machine description template
2 ;; Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004
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 2, 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 COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; Constraints
26 ;; a  $0
27 ;; b  $1
28 ;; c  $2
29 ;; d  $8
30 ;; e  $0..$7
31 ;; t  $0..$1
32 ;; y  Carry
33 ;; z  $8..$9
34 ;; I  0..3
35 ;; J  2**N mask
36 ;; K  2**N antimask
37 ;; L  0..255
38 ;; M  -255..0
39 ;; N  -3..0
40 ;; O  1..4
41 ;; P  -4..-1
42 ;; Q  post-inc mem (push)
43 ;; R  pre-dec mem (pop)
44 ;; S  immediate mem
45 ;; T  Rx
46 ;; U  -inf..1 or 16..inf
47 ;; Z  0
48
49 \f
50 ;; ::::::::::::::::::::
51 ;; ::
52 ;; :: Attributes
53 ;; ::
54 ;; ::::::::::::::::::::
55
56 ; Categorize branches for the conditional in the length attribute.
57 (define_attr "branch_class" "notdirectbranch,br12,bcc12,bcc8p2,bcc8p4" 
58     (const_string "notdirectbranch"))
59
60 ; The length of an instruction, used for branch shortening.
61 (define_attr "length" "" 
62   (cond
63    [(eq_attr "branch_class" "br12")
64      (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2046))
65                         (lt (minus (match_dup 0) (pc)) (const_int 2048)))
66                    (const_int 2)
67                    (const_int 4))
68     (eq_attr "branch_class" "bcc12")
69      (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
70                         (lt (minus (match_dup 0) (pc)) (const_int 2048)))
71                    (const_int 4)
72                    (const_int 8))
73     (eq_attr "branch_class" "bcc8p2")
74      (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -124))
75                         (lt (minus (match_dup 0) (pc)) (const_int 128)))
76                    (const_int 4)
77                    (const_int 8))
78     (eq_attr "branch_class" "bcc8p4")
79      (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -122))
80                         (lt (minus (match_dup 0) (pc)) (const_int 128)))
81                    (const_int 6)
82                    (const_int 10))]
83    (const_int 2)))
84
85 ; The operand which determines the setting of Rpsw.
86 ; The numbers indicate the operand number,
87 ; 'clobber' indicates it is changed in some unspecified way
88 ; 'nop' means it is not changed.
89 (define_attr "psw_operand" "clobber,nop,0,1,2,3,4" (const_string "0"))
90
91 (define_asm_attributes [(set_attr "length" "4")
92                         (set_attr "psw_operand" "clobber")])
93
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 "pushqi"
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 "popqi"
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 "pushhi"
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 "pophi"
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 ;; restires 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")])