OSDN Git Service

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