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
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
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
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
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
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
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
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
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
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
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
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
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
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")])
1373