xref: /openbsd/gnu/gcc/gcc/config/m88k/m88k.md (revision 5780af82)
1;;- Machine description for the Motorola 88000 for GNU C compiler
2;;  Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
3;;  Free Software Foundation, Inc.
4;;  Contributed by Michael Tiemann (tiemann@mcc.com)
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
24;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
26(define_constants
27  [(UNSPEC_ABDIFF	0)
28   (UNSPEC_GOT_REL	1)
29  ])
30
31(include "predicates.md")
32(include "constraints.md")
33
34;; Attribute describing the processor.  This attribute must match exactly
35;; with the processor_type enumeration in m88k.h.
36
37; Target CPU.
38(define_attr "cpu" "m88100,m88110,m88000"
39  (const (symbol_ref "m88k_cpu")))
40
41; Type of each instruction.  Default is arithmetic.
42; I'd like to write the list as this, but genattrtab won't accept it.
43;
44; "branch,jump,call,			; flow-control instructions
45;  load,store,loadd,loada,		; data unit instructions
46;  spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
47;  spmul,dpmul,imul,			; FPU multiply instructions
48;  arith,bit,mov			; integer unit instructions
49;  marith,weird"			; multi-word instructions
50
51; Classification of each insn.  Some insns of TYPE_BRANCH are multi-word.
52(define_attr "type"
53  "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
54  (const_string "arith"))
55
56(define_attr "fpu" "yes,no"
57  (if_then_else
58   (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
59   (const_string "yes") (const_string "no")))
60
61; Length in # of instructions of each insn.  The values are not exact, but
62; are safe.
63(define_attr "length" ""
64  (cond [(eq_attr "type" "marith,weird,branch")
65	 (const_int 2)]
66	(const_int 1)))
67
68; Describe a user's asm statement.
69(define_asm_attributes
70  [(set_attr "type" "weird")
71   (set_attr "length" "1")])
72
73; Define the delay slot requirements for branches and calls.
74; The m88100 annuls instructions if a conditional branch is taken.
75; For insns of TYPE_BRANCH that are multi-word instructions, the
76; delay slot applies to the first instruction.
77
78; @@ For the moment, reorg.c requires that the delay slot of a branch not
79; be a call or branch.
80
81(define_delay (eq_attr "type" "branch,jump")
82  [(and (and (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
83	     (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
84	(eq_attr "fpu" "no")) ; issue as-soon-as-possible.
85   (eq_attr "type" "!call,branch,jump") (nil)])
86
87; output_call supports an unconditional branch in the delay slot of
88; a call.  (@@ Support for this case is expected in reorg.c soon.)
89
90(define_delay (eq_attr "type" "call")
91  [(eq_attr "type" "!branch,call,marith,weird") ; required.
92   (nil) (nil)])
93
94;; Scheduling information
95
96;; This section is derived from the old define_function_unit description.
97;; Each reservation can be overriden on a processor-by-processor basis.
98
99; An abstract block diagram of the function units for the m88100.
100;
101;			    *
102;			    |
103;			+---v----+
104;			| decode |
105;			+-vv-v-v-+	 fpu
106;	       ,----------'| | `----------------------.
107;	       |	   | |			      |	,-----.
108;	  load |     store | | arith		      |	|     |
109;	       |	   | |			    +-v-v-+   |	dp source
110;	       |	   | |			    | fp1 |---'
111;     store    |	   | |	    div		    +-v-v-+
112;   ,------.   |	   | |	  ,-----. ,-----------'	`-----------.
113;   |	   |   |	   | |	  |	| |			    |
114;   |	+--v---v--+    ,---' |	  |   +-v-v---+			+---v---+
115;   |	| stage	2 |    |     |	  `---|	add 2 |			| mul 2	|
116;   |	+---------+    |  +--v--+     +-------+		  imul	+-------+
117;   |	| stage	1 |    |  | alu	|     |	add 3 |	       ,--------| mul 3	|
118;   |	+---------+    |  +--v--+     +-------+	       |	+-------+
119;   |	| stage	0 |    |     |	      |	add 4 |	       |	| mul 4	|
120;   |	+--v---v--+    |     |	      +---v---+	       |	+-------+
121;   |	   |   |       |     |		  |	       |	| mul 5	|
122;   |	   *   |       |     |		  |	       |	+---v---+
123;   |	       |       |     |		  |	  +----v----+	    |
124;   |	  load |       |     |	   fp add `------>| fp last |<------' fp mul
125;   |	       |       |     |			  +---v-v--^+
126;   |	       |       |     |			      |	|  |
127;   |	       |       |     |			      |	`--' dp	dest
128;   |	       |    +--v-----v--+		      |
129;   |	       `--->| writeback	|<--------------------'
130;   |		    +--v-----v--+
131;   |		       |     |
132;   `------------------'     *
133;
134; The decode unit need not be specified.
135; Consideration of writeback contention is critical to superb scheduling.
136
137(define_automaton "alu,fpu")
138
139(define_cpu_unit "alu" "alu")
140(define_cpu_unit "fpu" "fpu")
141
142(define_insn_reservation "generic_alu" 1
143 (eq_attr "type" "!store,marith,weird")
144 "alu")
145
146(define_insn_reservation "generic_alu_2" 2
147 (eq_attr "type" "marith,weird")
148 "alu")
149
150; 88100 specific
151
152(define_insn_reservation "store_88100" 1
153 (and (eq_attr "cpu" "m88100")
154      (eq_attr "type" "store,loada"))
155 "alu")
156
157(define_insn_reservation "load_88100" 3
158 (and (eq_attr "cpu" "m88100")
159      (eq_attr "type" "load"))
160 "alu")
161
162(define_insn_reservation "loadd_88100" 3
163 (and (eq_attr "cpu" "m88100")
164      (eq_attr "type" "loadd"))
165 "alu*2")
166
167; The times are adjusted to include fp1 and fplast, but then are further
168; adjusted based on the actual generated code.  The notation to the right
169; is the total latency.  A range denotes a group of instructions and/or
170; conditions (the extra clock of fplast time with some sequences).
171
172(define_insn_reservation "spmul_88100" 4
173 (and (eq_attr "cpu" "m88100")
174      (eq_attr "type" "spmul"))
175 "fpu")									; 6-8
176(define_insn_reservation "dpmul_88100" 7
177 (and (eq_attr "cpu" "m88100")
178      (eq_attr "type" "dpmul"))
179 "fpu")									; 9-10
180(define_insn_reservation "imul_88100" 3
181 (and (eq_attr "cpu" "m88100")
182      (eq_attr "type" "imul"))
183 "fpu")									; 4
184
185(define_insn_reservation "spdiv_88100" 30
186 (and (eq_attr "cpu" "m88100")
187      (eq_attr "type" "spdiv"))
188 "fpu")									; 30-31
189(define_insn_reservation "dpdiv_88100" 60
190 (and (eq_attr "cpu" "m88100")
191      (eq_attr "type" "dpdiv"))
192 "fpu")									; 60-61
193(define_insn_reservation "idiv_88100" 38
194 (and (eq_attr "cpu" "m88100")
195      (eq_attr "type" "idiv"))
196 "fpu")									; 38
197
198(define_insn_reservation "spadd_88100" 3
199 (and (eq_attr "cpu" "m88100")
200      (eq_attr "type" "spadd,spcmp"))
201 "fpu")									; 5-6
202(define_insn_reservation "dpadd_88100" 4
203 (and (eq_attr "cpu" "m88100")
204      (eq_attr "type" "dpadd,dpcmp"))
205 "fpu")									; 6-7
206
207; 88110 specific
208
209(define_insn_reservation "alu_88110" 2
210 (and (eq_attr "cpu" "!m88100")
211      (eq_attr "type" "loada,arith,mov"))
212 "alu")
213(define_insn_reservation "arith_88110" 4
214 (and (eq_attr "cpu" "!m88100")
215      (eq_attr "type" "marith,weird"))
216 "alu")
217
218(define_insn_reservation "bit_88110" 2
219 (and (eq_attr "cpu" "!m88100")
220      (eq_attr "type" "bit"))
221 "alu*2")
222
223(define_insn_reservation "load_88110" 3
224 (and (eq_attr "cpu" "!m88100")
225      (eq_attr "type" "load,loadd"))
226 "alu*2")
227(define_insn_reservation "store_88110" 1
228 (and (eq_attr "cpu" "!m88100")
229      (eq_attr "type" "store"))
230 "alu*2")
231
232(define_insn_reservation "spdiv_88110" 25
233 (and (eq_attr "cpu" "!m88100")
234      (eq_attr "type" "spdiv"))
235 "fpu*2")								; 13
236(define_insn_reservation "dpdiv_88110" 45
237 (and (eq_attr "cpu" "!m88100")
238      (eq_attr "type" "dpdiv"))
239 "fpu*2")								; 23
240(define_insn_reservation "idiv_88110" 35
241 (and (eq_attr "cpu" "!m88100")
242      (eq_attr "type" "idiv"))
243 "fpu*2")								; 18
244
245(define_insn_reservation "mul_88110" 5
246 (and (eq_attr "cpu" "!m88100")
247      (eq_attr "type" "imul,spmul,dpmul"))
248 "fpu*2")								; 3
249
250(define_insn_reservation "fpadd_88110" 5
251 (and (eq_attr "cpu" "!m88100")
252      (eq_attr "type" "spadd,dpadd"))
253 "fpu*2")								; 3
254(define_insn_reservation "fpcmp_88110" 2
255 (and (eq_attr "cpu" "!m88100")
256      (eq_attr "type" "spcmp,dpcmp"))
257 "fpu*2")								; 1
258
259;; Superoptimizer sequences
260
261;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
262;;      subu.co r5,r2,r3
263;;      addu.cio r6,r4,r0
264
265(define_split
266  [(set (match_operand:SI 0 "register_operand" "")
267	(minus:SI (match_operand:SI 1 "register_operand" "")
268		  (geu:SI (match_operand:SI 2 "register_operand" "")
269			  (match_operand:SI 3 "register_operand" ""))))]
270  "GET_CODE (operands[0]) == REG
271   && GET_CODE (operands[1]) == REG
272   && GET_CODE (operands[2]) == REG
273   && GET_CODE (operands[3]) == REG"
274  [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
275   (set (match_dup 0)
276	(plus:SI (match_dup 1)
277		 (unspec:SI [(const_int 0)
278			     (reg:CC 0)] 0)))]
279  "")
280
281;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
282;;      subu.co r5,r3,r2
283;;      addu.cio r6,r4,r0
284
285(define_split
286  [(set (match_operand:SI 0 "register_operand" "")
287	(minus:SI (match_operand:SI 1 "register_operand" "")
288		  (leu:SI (match_operand:SI 3 "register_operand" "")
289			  (match_operand:SI 2 "register_operand" ""))))]
290  "GET_CODE (operands[0]) == REG
291   && GET_CODE (operands[1]) == REG
292   && GET_CODE (operands[2]) == REG
293   && GET_CODE (operands[3]) == REG"
294  [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
295   (set (match_dup 0)
296	(plus:SI (match_dup 1)
297		 (unspec:SI [(const_int 0)
298			     (reg:CC 0)] 0)))]
299  "")
300
301;; eq0+: { r = (v0 == 0) + v1; }
302;;      subu.co r4,r0,r2
303;;      addu.cio r5,r3,r0
304
305(define_split
306  [(set (match_operand:SI 0 "register_operand" "")
307	(minus:SI (match_operand:SI 1 "register_operand" "")
308		  (eq:SI (match_operand:SI 2 "register_operand" "")
309			 (const_int 0))))]
310  "GET_CODE (operands[0]) == REG
311   && GET_CODE (operands[1]) == REG
312   && GET_CODE (operands[2]) == REG"
313  [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
314   (set (match_dup 0)
315	(plus:SI (match_dup 1)
316		 (unspec:SI [(const_int 0)
317			     (reg:CC 0)] 0)))]
318  "")
319
320;; ltu-:  { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
321;;      subu.co r5,r2,r3
322;;      subu.cio r6,r4,r0
323
324(define_split
325  [(set (match_operand:SI 0 "register_operand" "")
326	(plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "")
327			 (match_operand:SI 3 "register_operand" ""))
328		 (match_operand:SI 1 "register_operand" "")))]
329  "GET_CODE (operands[0]) == REG
330   && GET_CODE (operands[1]) == REG
331   && GET_CODE (operands[2]) == REG
332   && GET_CODE (operands[3]) == REG"
333  [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
334   (set (match_dup 0)
335	(minus:SI (match_dup 1)
336		  (unspec:SI [(const_int 0)
337			      (reg:CC 0)] 1)))]
338  "")
339
340;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
341;;      subu.co r5,r3,r2
342;;      subu.cio r6,r4,r0
343
344(define_split
345  [(set (match_operand:SI 0 "register_operand" "")
346	(plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "")
347			 (match_operand:SI 2 "register_operand" ""))
348		 (match_operand:SI 1 "register_operand" "")))]
349  "GET_CODE (operands[0]) == REG
350   && GET_CODE (operands[1]) == REG
351   && GET_CODE (operands[2]) == REG
352   && GET_CODE (operands[3]) == REG"
353  [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
354   (set (match_dup 0)
355	(minus:SI (match_dup 1)
356		 (unspec:SI [(const_int 0)
357			     (reg:CC 0)] 1)))]
358  "")
359
360;; ne0-: { r = v1 - (v0 != 0); }
361;;      subu.co r4,r0,r2
362;;      subu.cio r5,r3,r0
363
364(define_split
365  [(set (match_operand:SI 0 "register_operand" "")
366	(plus:SI (ne:SI (match_operand:SI 2 "register_operand" "")
367			(const_int 0))
368		 (match_operand:SI 1 "register_operand" "")))]
369  "GET_CODE (operands[0]) == REG
370   && GET_CODE (operands[1]) == REG
371   && GET_CODE (operands[2]) == REG"
372  [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
373   (set (match_dup 0)
374	(minus:SI (match_dup 1)
375		  (unspec:SI [(const_int 0)
376			      (reg:CC 0)] 1)))]
377  "")
378
379;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
380;;	addu.co	r4,r2,r2
381;;	subu.cio r5,r3,r0
382
383(define_split
384  [(set (match_operand:SI 0 "register_operand" "")
385	(minus:SI (match_operand:SI 1 "register_operand" "")
386		  (xor:SI (lshiftrt:SI
387			   (match_operand:SI 2 "register_operand" "")
388			   (const_int 31))
389			  (const_int 1))))]
390  "GET_CODE (operands[0]) == REG
391   && GET_CODE (operands[1]) == REG
392   && GET_CODE (operands[2]) == REG"
393  [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
394   (set (match_dup 0)
395	(minus:SI (match_dup 1)
396		  (unspec:SI [(const_int 0)
397			      (reg:CC 0)] 1)))]
398  "")
399
400;; This rich set of complex patterns are mostly due to Torbjorn Granlund
401;; (tege@sics.se).  They've changed since then, so don't complain to him
402;; if they don't work right.
403
404;; Regarding shifts, gen_lshlsi3 generates ASHIFT.  The gen functions
405;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
406;; special needs to be done here.
407
408;; Optimize possible cases of the set instruction.
409
410(define_insn ""
411  [(set (match_operand:SI 0 "register_operand" "=r")
412        (ashift:SI (const_int -1)
413       	    (match_operand:SI 1 "register_operand" "r")))]
414  ""
415  "set %0,%#r0,%1"
416  [(set_attr "type" "bit")])
417
418(define_insn ""
419  [(set (match_operand:SI 0 "register_operand" "=r")
420        (ior:SI (ashift:SI (const_int -1)
421       		    (match_operand:SI 1 "register_operand" "r"))
422       	 (match_operand:SI 2 "register_operand" "r")))]
423  ""
424  "set %0,%2,%1"
425  [(set_attr "type" "bit")])
426
427(define_insn ""
428  [(set (match_operand:SI 0 "register_operand" "=r")
429        (ior:SI (match_operand:SI 1 "register_operand" "r")
430       	 (ashift:SI (const_int -1)
431       		    (match_operand:SI 2 "register_operand" "r"))))]
432  ""
433  "set %0,%1,%2"
434  [(set_attr "type" "bit")])
435
436;; Optimize possible cases of the mak instruction.
437
438(define_insn ""
439  [(set (match_operand:SI 0 "register_operand" "=r")
440	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
441			   (match_operand:SI 2 "int5_operand" ""))
442		(match_operand:SI 3 "immediate_operand" "n")))]
443  "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
444{
445  operands[4] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3])
446					  >> INTVAL(operands[2]))));
447  return "mak %0,%1,%4<%2>";
448}
449  [(set_attr "type" "bit")])
450
451;; Optimize possible cases of output_and.
452
453(define_insn ""
454  [(set (match_operand:SI 0 "register_operand" "=r")
455	(ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
456				    (match_operand:SI 2 "int5_operand" "")
457				    (match_operand:SI 3 "int5_operand" ""))
458		   (match_operand:SI 4 "int5_operand" "")))]
459  "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
460{
461  operands[2]
462    = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
463  return output_and (operands);
464}
465  [(set_attr "type" "marith")]) ; arith,bit,marith.  length is 1 or 2.
466
467;; Improve logical operations on compare words
468;;
469;; We define all logical operations on CCmode values to preserve the pairwise
470;; relationship of the compare bits.  This allows a future branch prediction
471;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
472;; THIS IS CURRENTLY FALSE!
473;;
474;; Opportunities arise when conditional expressions using && and || are made
475;; unconditional.  When these are used to branch, the sequence is
476;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}.  When these are used to create
477;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
478;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
479;;
480;; When the extracted conditions are the same, the define_split patterns
481;; below change extu/extu/{and,or} into {and,or}/extu.  If the reversed
482;; conditions match, one compare word can be complemented, resulting in
483;; {and.c,or.c}/extu.  These changes are done for ext/ext/{and,or} as well.
484;; If the conditions don't line up, one can be rotated.  To keep the pairwise
485;; relationship, it may be necessary to both rotate and complement.  Rotating
486;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
487;; we don't do this for ext/ext/{and,or}.
488;;
489;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
490;; into an alternate form of bb0 and bb1.
491
492(define_split
493  [(set (match_operand:SI 0 "register_operand" "")
494	(ior:SI (neg:SI
495		 (match_operator 1 "even_relop"
496				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
497				  (const_int 0)]))
498		(neg:SI
499		 (match_operator 3 "relop"
500				 [(match_operand 4 "partial_ccmode_register_operand" "r")
501				  (const_int 0)]))))
502   (clobber (match_operand:SI 5 "register_operand" ""))]
503  "reload_completed
504   && GET_CODE (operands[0]) == REG"
505  [(set (match_dup 5)
506	(ior:CCEVEN (match_dup 4)
507		    (match_dup 2)))
508   (set (match_dup 0)
509	(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
510  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
511   if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
512     ; /* The conditions match.  */
513   else if (GET_CODE (operands[1])
514	    == reverse_condition (GET_CODE (operands[3])))
515     /* Reverse the condition by complementing the compare word.  */
516     operands[4] = gen_rtx_NOT (CCmode, operands[4]);
517   else
518     {
519       /* Make the condition pairs line up by rotating the compare word.  */
520       int cv1 = condition_value (operands[1]);
521       int cv2 = condition_value (operands[3]);
522
523       operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4],
524				     GEN_INT (((cv2 & ~1) - (cv1 & ~1))
525					      & 0x1f));
526       /* Reverse the condition if needed.  */
527       if ((cv1 & 1) != (cv2 & 1))
528	 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
529     }")
530
531(define_split
532  [(set (match_operand:SI 0 "register_operand" "")
533	(ior:SI (neg:SI
534		 (match_operator 1 "odd_relop"
535				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
536				  (const_int 0)]))
537		(neg:SI
538		 (match_operator 3 "odd_relop"
539				 [(match_operand 4 "partial_ccmode_register_operand" "r")
540				  (const_int 0)]))))
541   (clobber (match_operand:SI 5 "register_operand" ""))]
542  "reload_completed
543   && GET_CODE (operands[0]) == REG"
544  [(set (match_dup 5)
545	(and:CCEVEN (match_dup 4)
546		    (match_dup 2)))
547   (set (match_dup 0)
548	(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
549  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
550   if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
551     ; /* The conditions match.  */
552   else
553     {
554       /* Make the condition pairs line up by rotating the compare word.  */
555       int cv1 = condition_value (operands[1]);
556       int cv2 = condition_value (operands[3]);
557
558       operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4],
559				     GEN_INT ((cv2 - cv1) & 0x1f));
560     }")
561
562(define_split
563  [(set (match_operand:SI 0 "register_operand" "")
564	(ior:SI (neg:SI
565		 (match_operator 1 "odd_relop"
566				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
567				  (const_int 0)]))
568		(neg:SI
569		 (match_operator 3 "even_relop"
570				 [(match_operand 4 "partial_ccmode_register_operand" "r")
571				  (const_int 0)]))))
572   (clobber (match_operand:SI 5 "register_operand" ""))]
573  "reload_completed
574   && GET_CODE (operands[0]) == REG"
575  [(set (match_dup 5)
576	(ior:CCEVEN (not:CC (match_dup 2))
577		    (match_dup 4)))
578   (set (match_dup 0)
579	(neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
580  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
581  if (GET_CODE (operands[1])
582	    == reverse_condition (GET_CODE (operands[3])))
583     ;
584   else
585     {
586       /* Make the condition pairs line up by rotating the compare word.  */
587       int cv1 = condition_value (operands[1]);
588       int cv2 = condition_value (operands[3]);
589
590       operands[2] = gen_rtx_ROTATE (CCEVENmode, operands[2],
591				     GEN_INT (((cv1 & ~1) - (cv2 & ~1))
592					      & 0x1f));
593     }")
594
595(define_split
596  [(set (match_operand:SI 0 "register_operand" "")
597	(ior:SI (match_operator 1 "even_relop"
598				[(match_operand 2 "partial_ccmode_register_operand" "%r")
599				 (const_int 0)])
600		(match_operator 3 "relop"
601				[(match_operand 4 "partial_ccmode_register_operand" "r")
602				 (const_int 0)])))
603   (clobber (match_operand:SI 5 "register_operand" ""))]
604  "reload_completed
605   && GET_CODE (operands[0]) == REG
606   && (GET_CODE (operands[1]) == GET_CODE (operands[3])
607       || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3])))"
608  [(set (match_dup 5)
609	(ior:CCEVEN (match_dup 4)
610		    (match_dup 2)))
611   (set (match_dup 0)
612	(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
613  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
614   /* Reverse the condition by complementing the compare word.  */
615   if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
616      operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
617
618(define_split
619  [(set (match_operand:SI 0 "register_operand" "")
620	(ior:SI (match_operator 1 "odd_relop"
621				[(match_operand 2 "partial_ccmode_register_operand" "%r")
622				 (const_int 0)])
623		(match_operator 3 "odd_relop"
624				[(match_operand 4 "partial_ccmode_register_operand" "r")
625				 (const_int 0)])))
626   (clobber (match_operand:SI 5 "register_operand" ""))]
627  "reload_completed
628   && GET_CODE (operands[0]) == REG
629   && GET_CODE (operands[1]) == GET_CODE (operands[3])"
630  [(set (match_dup 5)
631	(and:CCEVEN (match_dup 4)
632		    (match_dup 2)))
633   (set (match_dup 0)
634	(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
635  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
636
637(define_split
638  [(set (match_operand:SI 0 "register_operand" "")
639	(ior:SI (match_operator 1 "odd_relop"
640				[(match_operand 2 "partial_ccmode_register_operand" "%r")
641				 (const_int 0)])
642		(match_operator 3 "even_relop"
643				[(match_operand 4 "partial_ccmode_register_operand" "r")
644				 (const_int 0)])))
645   (clobber (match_operand:SI 5 "register_operand" ""))]
646  "reload_completed
647   && GET_CODE (operands[0]) == REG
648   && GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
649  [(set (match_dup 5)
650	(ior:CCEVEN (not:CC (match_dup 4))
651		    (match_dup 2)))
652   (set (match_dup 0)
653	(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
654  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
655
656(define_split
657  [(set (match_operand:SI 0 "register_operand" "")
658	(and:SI (neg:SI
659		 (match_operator 1 "even_relop"
660				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
661				  (const_int 0)]))
662		(neg:SI
663		 (match_operator 3 "relop"
664				 [(match_operand 4 "partial_ccmode_register_operand" "r")
665				  (const_int 0)]))))
666   (clobber (match_operand:SI 5 "register_operand" ""))]
667  "reload_completed
668   && GET_CODE (operands[0]) == REG"
669  [(set (match_dup 5)
670	(and:CCEVEN (match_dup 4)
671		    (match_dup 2)))
672   (set (match_dup 0)
673	(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
674  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
675   if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
676     ; /* The conditions match.  */
677   else if (GET_CODE (operands[1])
678	    == reverse_condition (GET_CODE (operands[3])))
679     /* Reverse the condition by complementing the compare word.  */
680     operands[4] = gen_rtx_NOT (CCmode, operands[4]);
681   else
682     {
683       /* Make the condition pairs line up by rotating the compare word.  */
684       int cv1 = condition_value (operands[1]);
685       int cv2 = condition_value (operands[3]);
686       operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
687				     GEN_INT (((cv2 & ~1) - (cv1 & ~1))
688					      & 0x1f));
689       /* Reverse the condition if needed.  */
690       if ((cv1 & 1) != (cv2 & 1))
691	 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
692     }")
693
694(define_split
695  [(set (match_operand:SI 0 "register_operand" "")
696	(and:SI (neg:SI
697		 (match_operator 1 "odd_relop"
698				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
699				  (const_int 0)]))
700		(neg:SI
701		 (match_operator 3 "odd_relop"
702				 [(match_operand 4 "partial_ccmode_register_operand" "r")
703				  (const_int 0)]))))
704   (clobber (match_operand:SI 5 "register_operand" ""))]
705  "reload_completed
706   && GET_CODE (operands[0]) == REG"
707  [(set (match_dup 5)
708	(ior:CCEVEN (match_dup 4)
709		    (match_dup 2)))
710   (set (match_dup 0)
711	(neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
712  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
713   if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
714     ; /* The conditions match.  */
715   else
716     {
717       /* Make the condition pairs line up by rotating the compare word.  */
718       int cv1 = condition_value (operands[1]);
719       int cv2 = condition_value (operands[3]);
720       operands[4] = gen_rtx_ROTATE (CCEVENmode, operands[4],
721				     GEN_INT ((cv2 - cv1) & 0x1f));
722     }")
723
724(define_split
725  [(set (match_operand:SI 0 "register_operand" "")
726	(and:SI (neg:SI
727		 (match_operator 1 "odd_relop"
728				 [(match_operand 2 "partial_ccmode_register_operand" "%r")
729				  (const_int 0)]))
730		(neg:SI
731		 (match_operator 3 "even_relop"
732				 [(match_operand 4 "partial_ccmode_register_operand" "r")
733				  (const_int 0)]))))
734   (clobber (match_operand:SI 5 "register_operand" ""))]
735  "reload_completed
736   && GET_CODE (operands[0]) == REG"
737  [(set (match_dup 5)
738	(and:CCEVEN (not:CC (match_dup 2))
739		    (match_dup 4)))
740   (set (match_dup 0)
741	(neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
742  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
743   if (GET_CODE (operands[1])
744	    == reverse_condition (GET_CODE (operands[3])))
745	;
746   else
747     {
748       /* Make the condition pairs line up by rotating the compare word.  */
749       int cv1 = condition_value (operands[1]);
750       int cv2 = condition_value (operands[3]);
751       operands[2] = gen_rtx_ROTATE (CCEVENmode, operands[2],
752				     GEN_INT (((cv1 & ~1) - (cv2 & ~1))
753					      & 0x1f));
754     }")
755
756(define_split
757  [(set (match_operand:SI 0 "register_operand" "")
758	(and:SI (match_operator 1 "even_relop"
759				[(match_operand 2 "partial_ccmode_register_operand" "%r")
760				 (const_int 0)])
761		(match_operator 3 "relop"
762				[(match_operand 4 "partial_ccmode_register_operand" "r")
763				 (const_int 0)])))
764   (clobber (match_operand:SI 5 "register_operand" ""))]
765  "reload_completed
766   && GET_CODE (operands[0]) == REG
767   && (GET_CODE (operands[1]) == GET_CODE (operands[3])
768       || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3])))"
769  [(set (match_dup 5)
770	(and:CCEVEN (match_dup 4)
771		    (match_dup 2)))
772   (set (match_dup 0)
773	(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
774  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
775   /* Reverse the condition by complementing the compare word.  */
776   if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
777      operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
778
779(define_split
780  [(set (match_operand:SI 0 "register_operand" "")
781	(and:SI (match_operator 1 "odd_relop"
782				[(match_operand 2 "partial_ccmode_register_operand" "%r")
783				 (const_int 0)])
784		(match_operator 3 "odd_relop"
785				[(match_operand 4 "partial_ccmode_register_operand" "r")
786				 (const_int 0)])))
787   (clobber (match_operand:SI 5 "register_operand" ""))]
788  "reload_completed
789   && GET_CODE (operands[0]) == REG
790   && GET_CODE (operands[1]) == GET_CODE (operands[3])"
791  [(set (match_dup 5)
792	(ior:CCEVEN (match_dup 4)
793		    (match_dup 2)))
794   (set (match_dup 0)
795	(match_op_dup 1 [(match_dup 5) (const_int 0)]))]
796  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
797
798(define_split
799  [(set (match_operand:SI 0 "register_operand" "")
800	(and:SI (match_operator 1 "odd_relop"
801				[(match_operand 2 "partial_ccmode_register_operand" "%r")
802				 (const_int 0)])
803		(match_operator 3 "even_relop"
804				[(match_operand 4 "partial_ccmode_register_operand" "r")
805				 (const_int 0)])))
806   (clobber (match_operand:SI 5 "register_operand" ""))]
807  "reload_completed
808   && GET_CODE (operands[0]) == REG
809   && GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
810  [(set (match_dup 5)
811	(and:CCEVEN (not:CC (match_dup 2))
812		    (match_dup 4)))
813   (set (match_dup 0)
814	(match_op_dup 3 [(match_dup 5) (const_int 0)]))]
815  "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
816
817
818;; Logical operations on compare words.
819
820(define_insn ""
821  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
822	(and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
823		    (match_operand 2 "partial_ccmode_register_operand" "r")))]
824  ""
825  "and.c %0,%2,%1")
826
827(define_insn ""
828  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
829	(and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
830		    (match_operand 2 "partial_ccmode_register_operand" "r")))]
831  ""
832  "and %0,%1,%2")
833
834(define_insn ""
835  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
836	(ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
837		    (match_operand 2 "partial_ccmode_register_operand" "r")))]
838  ""
839  "or.c %0,%2,%1")
840
841(define_insn ""
842  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
843	(ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
844		    (match_operand 2 "partial_ccmode_register_operand" "r")))]
845  ""
846  "or %0,%1,%2")
847
848(define_insn ""
849  [(set (match_operand:CC 0 "register_operand" "=r")
850	(rotate:CC (match_operand:CC 1 "register_operand" "r")
851		   (match_operand:CC 2 "int5_operand" "")))]
852  ""
853  "rot %0,%1,%2"
854  [(set_attr "type" "bit")])
855
856(define_insn ""
857  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
858	(rotate:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "r")
859		       (match_operand:CC 2 "int5_operand" "")))]
860  ""
861  "rot %0,%1,%2"
862  [(set_attr "type" "bit")])
863
864;; rotate/and[.c] and rotate/ior[.c]
865
866(define_split
867  [(set (match_operand:CCEVEN 0 "register_operand" "")
868	(ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "")
869			       (match_operand:CC 2 "int5_operand" ""))
870		    (match_operand 3 "partial_ccmode_register_operand" "")))
871   (clobber (match_operand:CCEVEN 4 "register_operand" ""))]
872  "reload_completed
873   && GET_CODE (operands[0]) == REG
874   && partial_ccmode_register_operand (operands[1], VOIDmode)
875   && partial_ccmode_register_operand (operands[3], VOIDmode)"
876  [(set (match_dup 4)
877	(rotate:CC (match_dup 1) (match_dup 2)))
878   (set (match_dup 0)
879	(ior:CCEVEN (match_dup 4) (match_dup 3)))]
880  "")
881
882(define_insn ""
883  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
884	(ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
885			       (match_operand:CC 2 "int5_operand" ""))
886		(match_operand 3 "partial_ccmode_register_operand" "r")))
887   (clobber (match_scratch:CCEVEN 4 "=r"))]
888  ""
889  "#")
890
891(define_split
892  [(set (match_operand:CCEVEN 0 "register_operand" "")
893	(ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "")
894				       (match_operand:CC 2 "int5_operand" "")))
895		(match_operand 3 "partial_ccmode_register_operand" "")))
896   (clobber (match_operand:CCEVEN 4 "register_operand" ""))]
897  "reload_completed
898   && GET_CODE (operands[0]) == REG
899   && partial_ccmode_register_operand (operands[1], VOIDmode)
900   && partial_ccmode_register_operand (operands[3], VOIDmode)"
901  [(set (match_dup 4)
902	(rotate:CC (match_dup 1) (match_dup 2)))
903   (set (match_dup 0)
904	(ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
905  "")
906
907(define_insn ""
908  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
909	(ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
910				       (match_operand:CC 2 "int5_operand" "")))
911		(match_operand 3 "partial_ccmode_register_operand" "r")))
912   (clobber (match_scratch:CCEVEN 4 "=r"))]
913  ""
914  "#")
915
916(define_split
917  [(set (match_operand:CCEVEN 0 "register_operand" "")
918	(and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "")
919			       (match_operand:CC 2 "int5_operand" ""))
920		(match_operand 3 "partial_ccmode_register_operand" "")))
921   (clobber (match_operand:CCEVEN 4 "register_operand" ""))]
922  "reload_completed
923   && GET_CODE (operands[0]) == REG
924   && partial_ccmode_register_operand (operands[1], VOIDmode)
925   && partial_ccmode_register_operand (operands[3], VOIDmode)"
926  [(set (match_dup 4)
927	(rotate:CC (match_dup 1) (match_dup 2)))
928   (set (match_dup 0)
929	(and:CCEVEN (match_dup 4) (match_dup 3)))]
930  "")
931
932(define_insn ""
933  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
934	(and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
935			       (match_operand:CC 2 "int5_operand" ""))
936		(match_operand 3 "partial_ccmode_register_operand" "r")))
937   (clobber (match_scratch:CCEVEN 4 "=r"))]
938  ""
939  "#")
940
941(define_split
942  [(set (match_operand:CCEVEN 0 "register_operand" "")
943	(and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "")
944				       (match_operand:CC 2 "int5_operand" "")))
945		(match_operand 3 "partial_ccmode_register_operand" "")))
946   (clobber (match_operand:CCEVEN 4 "register_operand" ""))]
947  "reload_completed
948   && GET_CODE (operands[0]) == REG
949   && partial_ccmode_register_operand (operands[1], VOIDmode)
950   && partial_ccmode_register_operand (operands[3], VOIDmode)"
951  [(set (match_dup 4)
952	(rotate:CC (match_dup 1) (match_dup 2)))
953   (set (match_dup 0)
954	(and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
955  "")
956
957(define_insn ""
958  [(set (match_operand:CCEVEN 0 "register_operand" "=r")
959	(and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
960				       (match_operand:CC 2 "int5_operand" "")))
961		(match_operand 3 "partial_ccmode_register_operand" "r")))
962   (clobber (match_scratch:CCEVEN 4 "=r"))]
963  ""
964  "#")
965
966
967;; Recognize bcnd instructions for integer values.  This is distinguished
968;; from a conditional branch instruction (below) with SImode instead of
969;; CCmode.
970
971(define_insn ""
972  [(set (pc)
973	(if_then_else
974	 (match_operator 0 "relop_no_unsigned"
975			 [(match_operand:SI 1 "register_operand" "r")
976			  (const_int 0)])
977	 (match_operand 2 "pc_or_label_ref" "")
978	 (match_operand 3 "pc_or_label_ref" "")))]
979  ""
980  "bcnd%. %R3%B0,%1,%P2%P3"
981  [(set_attr "type" "branch")])
982
983;; Recognize tests for sign and zero.
984
985(define_insn ""
986  [(set (pc)
987	(if_then_else
988	 (match_operator 0 "equality_op"
989			 [(match_operand:SI 1 "register_operand" "r")
990			  (const_int -2147483648)])
991	 (match_operand 2 "pc_or_label_ref" "")
992	 (match_operand 3 "pc_or_label_ref" "")))]
993  ""
994  "bcnd%. %R3%E0,%1,%P2%P3"
995  [(set_attr "type" "branch")])
996
997(define_insn ""
998  [(set (pc)
999	(if_then_else
1000	 (match_operator 0 "equality_op"
1001			 [(zero_extract:SI
1002			   (match_operand:SI 1 "register_operand" "r")
1003			   (const_int 31)
1004			   (const_int 1))
1005			  (const_int 0)])
1006	 (match_operand 2 "pc_or_label_ref" "")
1007	 (match_operand 3 "pc_or_label_ref" "")))]
1008  ""
1009  "bcnd%. %R3%D0,%1,%P2%P3"
1010  [(set_attr "type" "branch")])
1011
1012;; Recognize bcnd instructions for double integer values
1013
1014(define_insn ""
1015  [(set (pc)
1016	(if_then_else
1017	 (match_operator 0 "relop_no_unsigned"
1018			 [(sign_extend:DI
1019			   (match_operand:SI 1 "register_operand" "r"))
1020			  (const_int 0)])
1021	 (match_operand 2 "pc_or_label_ref" "")
1022	 (match_operand 3 "pc_or_label_ref" "")))]
1023  ""
1024  "bcnd%. %R3%B0,%1,%P2%P3"
1025  [(set_attr "type" "branch")])
1026
1027(define_insn ""
1028  [(set (pc)
1029	(if_then_else
1030	 (match_operator 0 "equality_op"
1031			 [(zero_extend:DI
1032			   (match_operand:SI 1 "register_operand" "r"))
1033			  (const_int 0)])
1034	 (match_operand 2 "pc_or_label_ref" "")
1035	 (match_operand 3 "pc_or_label_ref" "")))]
1036  ""
1037  "bcnd%. %R3%B0,%1,%P2%P3"
1038  [(set_attr "type" "branch")])
1039
1040;; Recognize bcnd instructions for single precision float values
1041;; Exclude relational operations as they must signal NaNs.
1042
1043;; @@ These bcnd insns for float and double values don't seem to be recognized.
1044
1045(define_insn ""
1046  [(set (pc)
1047	(if_then_else
1048	 (match_operator 0 "equality_op"
1049			 [(float_extend:DF
1050			   (match_operand:SF 1 "register_operand" "r"))
1051			  (const_int 0)])
1052	 (match_operand 2 "pc_or_label_ref" "")
1053	 (match_operand 3 "pc_or_label_ref" "")))]
1054  ""
1055  "bcnd%. %R3%D0,%1,%P2%P3"
1056  [(set_attr "type" "branch")])
1057
1058(define_insn ""
1059  [(set (pc)
1060	(if_then_else
1061	 (match_operator 0 "equality_op"
1062			 [(match_operand:SF 1 "register_operand" "r")
1063			  (const_int 0)])
1064	 (match_operand 2 "pc_or_label_ref" "")
1065	 (match_operand 3 "pc_or_label_ref" "")))]
1066  ""
1067  "bcnd%. %R3%D0,%1,%P2%P3"
1068  [(set_attr "type" "branch")])
1069
1070;; Recognize bcnd instructions for double precision float values
1071;; Exclude relational operations as they must signal NaNs.
1072
1073(define_insn ""
1074  [(set (pc)
1075	(if_then_else
1076	 (match_operator 0 "equality_op"
1077			 [(match_operand:DF 1 "register_operand" "r")
1078			  (const_int 0)])
1079	 (match_operand 2 "pc_or_label_ref" "")
1080	 (match_operand 3 "pc_or_label_ref" "")))]
1081  ""
1082{
1083  if (GET_CODE (operands[0]) == NE)
1084    {
1085      rtx op2 = operands[2];
1086      operands[2] = operands[3];
1087      operands[3] = op2;
1088    }
1089  if (GET_CODE (operands[3]) == LABEL_REF)
1090    return "bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3";
1091
1092  operands[3] = gen_label_rtx ();
1093  output_asm_insn ("bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2", operands);
1094  emit_label (operands[3]);
1095  return "";
1096}
1097  [(set_attr "type" "weird")
1098   (set_attr "length" "3")])
1099
1100;; Recognize bb0 and bb1 instructions.  These use two unusual template
1101;; patterns, %Lx and %Px.  %Lx outputs a 1 if operand `x' is a LABEL_REF
1102;; otherwise it outputs a 0.  It then may print ".n" if the delay slot
1103;; is used.  %Px does noting if `x' is PC and outputs the operand if `x'
1104;; is a LABEL_REF.
1105
1106(define_insn ""
1107  [(set (pc)
1108	(if_then_else
1109	 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1110			      (const_int 1)
1111			      (match_operand:SI 1 "int5_operand" ""))
1112	     (const_int 0))
1113	 (match_operand 2 "pc_or_label_ref" "")
1114	 (match_operand 3 "pc_or_label_ref" "")))]
1115  ""
1116  "bb%L2 (31-%1),%0,%P2%P3"
1117  [(set_attr "type" "branch")])
1118
1119(define_insn ""
1120  [(set (pc)
1121	(if_then_else
1122	 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1123			      (const_int 1)
1124			      (match_operand:SI 1 "int5_operand" ""))
1125	     (const_int 0))
1126	 (match_operand 2 "pc_or_label_ref" "")
1127	 (match_operand 3 "pc_or_label_ref" "")))]
1128  ""
1129  "bb%L3 (31-%1),%0,%P2%P3"
1130  [(set_attr "type" "branch")])
1131
1132(define_insn ""
1133  [(set (pc)
1134	(if_then_else
1135	 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1136			      (const_int 1)
1137			      (match_operand:SI 1 "int5_operand" ""))
1138	     (const_int 0))
1139	 (match_operand 2 "pc_or_label_ref" "")
1140	 (match_operand 3 "pc_or_label_ref" "")))]
1141  ""
1142  "bb%L2 (31-%1),%0,%P2%P3"
1143  [(set_attr "type" "branch")])
1144
1145(define_insn ""
1146  [(set (pc)
1147	(if_then_else
1148	 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1149			      (const_int 1)
1150			      (match_operand:SI 1 "int5_operand" ""))
1151	     (const_int 0))
1152	 (match_operand 2 "pc_or_label_ref" "")
1153	 (match_operand 3 "pc_or_label_ref" "")))]
1154  ""
1155  "bb%L3 (31-%1),%0,%P2%P3"
1156  [(set_attr "type" "branch")])
1157
1158(define_insn ""
1159  [(set (pc)
1160	(if_then_else
1161	 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1162		     (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1163	      (const_int 0))
1164	 (match_operand 2 "pc_or_label_ref" "")
1165	 (match_operand 3 "pc_or_label_ref" "")))]
1166  "(GET_CODE (operands[0]) == CONST_INT)
1167   != (GET_CODE (operands[1]) == CONST_INT)"
1168  "bb%L3 %p1,%0,%P2%P3"
1169  [(set_attr "type" "branch")])
1170
1171(define_insn ""
1172  [(set (pc)
1173	(if_then_else
1174	 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1175		     (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1176	     (const_int 0))
1177	 (match_operand 2 "pc_or_label_ref" "")
1178	 (match_operand 3 "pc_or_label_ref" "")))]
1179  "(GET_CODE (operands[0]) == CONST_INT)
1180   != (GET_CODE (operands[1]) == CONST_INT)"
1181  "bb%L2 %p1,%0,%P2%P3"
1182  [(set_attr "type" "branch")])
1183
1184;; The comparison operations store the comparison into a register and
1185;; record that register.  The following Bxx or Sxx insn uses that
1186;; register as an input.  To facilitate use of bcnd instead of cmp/bb1,
1187;; cmpsi records its operands and produces no code when any operand
1188;; is constant.  In this case, the Bxx insns use gen_bcnd and the
1189;; Sxx insns use gen_test to ensure a cmp has been emitted.
1190;;
1191;; This could also be done for SFmode and DFmode having only beq and bne
1192;; use gen_bcnd.  The others must signal NaNs.  It seems though that zero
1193;; has already been copied into a register.
1194;;
1195;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1196;; is a constant.  (This idea is due to Torbjorn Granlund.)  Others can
1197;; use bcnd only if an operand is zero.
1198;;
1199;; It is necessary to distinguish a register holding condition codes.
1200;; This is done by context.
1201
1202(define_expand "test"
1203  [(set (match_dup 2)
1204	(compare:CC (match_operand 0 "" "")
1205		    (match_operand 1 "" "")))]
1206  ""
1207  "
1208{
1209  gcc_assert (m88k_compare_reg == NULL_RTX);
1210
1211  if (GET_CODE (operands[0]) == CONST_INT
1212      && ! SMALL_INT (operands[0]))
1213    operands[0] = force_reg (SImode, operands[0]);
1214
1215  if (GET_CODE (operands[1]) == CONST_INT
1216      && ! SMALL_INT (operands[1]))
1217    operands[1] = force_reg (SImode, operands[1]);
1218
1219  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1220}")
1221
1222(define_expand "cmpsi"
1223  [(set (match_dup 2)
1224	(compare:CC (match_operand:SI 0 "register_operand" "")
1225		    (match_operand:SI 1 "arith32_operand" "")))]
1226  ""
1227  "
1228{
1229  if (GET_CODE (operands[0]) == CONST_INT
1230      || GET_CODE (operands[1]) == CONST_INT)
1231    {
1232      m88k_compare_reg = NULL_RTX;
1233      m88k_compare_op0 = operands[0];
1234      m88k_compare_op1 = operands[1];
1235      DONE;
1236    }
1237  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1238}")
1239
1240(define_expand "cmpsf"
1241  [(set (match_dup 2)
1242	(compare:CC (match_operand:SF 0 "register_operand" "")
1243		    (match_operand:SF 1 "register_operand" "")))]
1244  ""
1245  "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1246
1247(define_expand "cmpdf"
1248  [(set (match_dup 2)
1249	(compare:CC (match_operand:DF 0 "general_operand" "")
1250		    (match_operand:DF 1 "general_operand" "")))]
1251  ""
1252  "
1253{
1254  operands[0] = legitimize_operand (operands[0], DFmode);
1255  operands[1] = legitimize_operand (operands[1], DFmode);
1256  operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1257}")
1258
1259;; The actual compare instructions.
1260
1261(define_insn ""
1262  [(set (match_operand:CC 0 "register_operand" "=r")
1263	(compare:CC (match_operand:SI 1 "register_operand" "rO")
1264		    (match_operand:SI 2 "arith_operand" "rI")))]
1265  ""
1266  "cmp %0,%r1,%2")
1267
1268(define_insn ""
1269  [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1270	(compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1271		    (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1272  ""
1273  "@
1274   fcmp.sss %0,%1,%2
1275   fcmp.sss %0,%1,%#r0
1276   fcmp.sss %0,%1,%2
1277   fcmp.sss %0,%1,%#x0"
1278  [(set_attr "type" "spcmp")])
1279
1280(define_insn ""
1281  [(set (match_operand:CC 0 "register_operand" "=r,r")
1282	(compare:CC (match_operand:DF 1 "register_operand" "r,x")
1283		    (float_extend:DF
1284		     (match_operand:SF 2 "register_operand" "r,x"))))]
1285  ""
1286  "fcmp.sds %0,%1,%2"
1287  [(set_attr "type" "dpcmp")])
1288
1289(define_insn ""
1290  [(set (match_operand:CC 0 "register_operand" "=r,r")
1291	(compare:CC (float_extend:DF
1292		     (match_operand:SF 1 "register_operand" "r,x"))
1293		    (match_operand:DF 2 "register_operand" "r,x")))]
1294  ""
1295  "fcmp.ssd %0,%1,%2"
1296  [(set_attr "type" "dpcmp")])
1297
1298(define_insn ""
1299  [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1300	(compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1301		    (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1302  ""
1303  "@
1304   fcmp.sdd %0,%1,%2
1305   fcmp.sds %0,%1,%#r0
1306   fcmp.sdd %0,%1,%2
1307   fcmp.sds %0,%1,%#x0"
1308  [(set_attr "type" "dpcmp")])
1309
1310;; Store condition code insns.  The compare insns set a register
1311;; rather than cc0 and record that register for use here.  See above
1312;; for the special treatment of cmpsi with a constant operand.
1313
1314;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1315
1316(define_expand "seq"
1317  [(set (match_operand:SI 0 "register_operand" "")
1318	(match_dup 1))]
1319  ""
1320  "operands[1] = emit_test (EQ, SImode);")
1321
1322(define_expand "sne"
1323  [(set (match_operand:SI 0 "register_operand" "")
1324	(match_dup 1))]
1325  ""
1326  "operands[1] = emit_test (NE, SImode);")
1327
1328(define_expand "sgt"
1329  [(set (match_operand:SI 0 "register_operand" "")
1330	(match_dup 1))]
1331  ""
1332  "operands[1] = emit_test (GT, SImode);")
1333
1334(define_expand "sgtu"
1335  [(set (match_operand:SI 0 "register_operand" "")
1336	(match_dup 1))]
1337  ""
1338  "operands[1] = emit_test (GTU, SImode);")
1339
1340(define_expand "slt"
1341  [(set (match_operand:SI 0 "register_operand" "")
1342	(match_dup 1))]
1343  ""
1344  "operands[1] = emit_test (LT, SImode);")
1345
1346(define_expand "sltu"
1347  [(set (match_operand:SI 0 "register_operand" "")
1348	(match_dup 1))]
1349  ""
1350  "operands[1] = emit_test (LTU, SImode);")
1351
1352(define_expand "sge"
1353  [(set (match_operand:SI 0 "register_operand" "")
1354	(match_dup 1))]
1355  ""
1356  "operands[1] = emit_test (GE, SImode);")
1357
1358(define_expand "sgeu"
1359  [(set (match_operand:SI 0 "register_operand" "")
1360	(match_dup 1))]
1361  ""
1362  "operands[1] = emit_test (GEU, SImode);")
1363
1364(define_expand "sle"
1365  [(set (match_operand:SI 0 "register_operand" "")
1366	(match_dup 1))]
1367  ""
1368  "operands[1] = emit_test (LE, SImode);")
1369
1370(define_expand "sleu"
1371  [(set (match_operand:SI 0 "register_operand" "")
1372	(match_dup 1))]
1373  ""
1374  "operands[1] = emit_test (LEU, SImode);")
1375
1376;; The actual set condition code instruction.
1377
1378(define_insn ""
1379  [(set (match_operand:SI 0 "register_operand" "=r")
1380	(match_operator:SI 1 "relop"
1381			   [(match_operand:CC 2 "register_operand" "r")
1382			    (const_int 0)]))]
1383  ""
1384  "ext %0,%2,1<%C1>"
1385  [(set_attr "type" "bit")])
1386
1387(define_insn ""
1388  [(set (match_operand:SI 0 "register_operand" "=r")
1389	(match_operator:SI 1 "even_relop"
1390			   [(match_operand:CCEVEN 2 "register_operand" "r")
1391			    (const_int 0)]))]
1392  ""
1393  "ext %0,%2,1<%C1>"
1394  [(set_attr "type" "bit")])
1395
1396(define_insn ""
1397  [(set (match_operand:SI 0 "register_operand" "=r")
1398	(not:SI (match_operator:SI 1 "odd_relop"
1399			   [(match_operand:CCEVEN 2 "register_operand" "r")
1400			    (const_int 0)])))]
1401  ""
1402  "ext %0,%2,1<%!%C1>"
1403  [(set_attr "type" "bit")])
1404
1405(define_split
1406  [(set (match_operand:SI 0 "register_operand" "")
1407	(match_operator:SI 1 "odd_relop"
1408			   [(match_operand:CCEVEN 2 "register_operand" "r")
1409			    (const_int 0)]))
1410   (clobber (match_operand:SI 3 "register_operand" ""))]
1411  "reload_completed
1412   && GET_CODE (operands[0]) == REG"
1413  [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1414   (set (match_dup 0) (not:SI (match_dup 3)))]
1415  "")
1416
1417(define_insn ""
1418  [(set (match_operand:SI 0 "register_operand" "=r")
1419	(match_operator:SI 1 "odd_relop"
1420			   [(match_operand:CCEVEN 2 "register_operand" "r")
1421			    (const_int 0)]))
1422   (clobber (match_scratch:SI 3 "=r"))]
1423  ""
1424  "#")
1425
1426(define_insn ""
1427  [(set (match_operand:SI 0 "register_operand" "=r")
1428	(neg:SI
1429	 (match_operator:SI 1 "relop"
1430			    [(match_operand:CC 2 "register_operand" "r")
1431			     (const_int 0)])))]
1432  ""
1433  "extu %0,%2,1<%C1>"
1434  [(set_attr "type" "bit")])
1435
1436(define_insn ""
1437  [(set (match_operand:SI 0 "register_operand" "=r")
1438	(neg:SI
1439	 (match_operator:SI 1 "even_relop"
1440			    [(match_operand:CCEVEN 2 "register_operand" "r")
1441			     (const_int 0)])))]
1442  ""
1443  "extu %0,%2,1<%C1>"
1444  [(set_attr "type" "bit")])
1445
1446(define_insn ""
1447  [(set (match_operand:SI 0 "register_operand" "=r")
1448	(neg:SI
1449	 (not:SI (match_operator:SI 1 "odd_relop"
1450			    [(match_operand:CCEVEN 2 "register_operand" "r")
1451			     (const_int 0)]))))]
1452  ""
1453  "extu %0,%2,1<%!%C1>"
1454  [(set_attr "type" "bit")])
1455
1456(define_split
1457  [(set (match_operand:SI 0 "register_operand" "")
1458	(neg:SI (match_operator:SI 1 "odd_relop"
1459			   [(match_operand:CCEVEN 2 "register_operand" "r")
1460			    (const_int 0)])))
1461   (clobber (match_operand:SI 3 "register_operand" ""))]
1462  "reload_completed
1463   && GET_CODE (operands[0]) == REG"
1464  [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1465                                                       (const_int 0)]))))
1466   (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1467  "")
1468
1469(define_insn
1470 ""
1471  [(set (match_operand:SI 0 "register_operand" "=r")
1472	(neg:SI (match_operator:SI 1 "odd_relop"
1473			   [(match_operand:CCEVEN 2 "register_operand" "r")
1474			    (const_int 0)])))
1475   (clobber (match_scratch:SI 3 "=r"))]
1476  ""
1477  "#")
1478
1479
1480
1481
1482;; Conditional branch insns.  The compare insns set a register
1483;; rather than cc0 and record that register for use here.  See above
1484;; for the special case of cmpsi with a constant operand.
1485
1486(define_expand "bcnd"
1487  [(set (pc)
1488	(if_then_else (match_operand 0 "" "")
1489		      (label_ref (match_operand 1 "" ""))
1490		      (pc)))]
1491  ""
1492  "gcc_assert (m88k_compare_reg == NULL_RTX);")
1493
1494(define_expand "bxx"
1495  [(set (pc)
1496	(if_then_else (match_operand 0 "" "")
1497		      (label_ref (match_operand 1 "" ""))
1498		      (pc)))]
1499  ""
1500  "gcc_assert (m88k_compare_reg != NULL_RTX);")
1501
1502(define_expand "beq"
1503  [(set (pc)
1504	(if_then_else (eq (match_dup 1) (const_int 0))
1505		      (label_ref (match_operand 0 "" ""))
1506		      (pc)))]
1507  ""
1508  "if (m88k_compare_reg == NULL_RTX)
1509     {
1510       emit_bcnd (EQ, operands[0]);
1511       DONE;
1512     }
1513   operands[1] = m88k_compare_reg;")
1514
1515(define_expand "bne"
1516  [(set (pc)
1517	(if_then_else (ne (match_dup 1) (const_int 0))
1518		      (label_ref (match_operand 0 "" ""))
1519		      (pc)))]
1520  ""
1521  "if (m88k_compare_reg == NULL_RTX)
1522     {
1523       emit_bcnd (NE, operands[0]);
1524       DONE;
1525     }
1526   operands[1] = m88k_compare_reg;")
1527
1528(define_expand "bgt"
1529  [(set (pc)
1530	(if_then_else (gt (match_dup 1) (const_int 0))
1531		      (label_ref (match_operand 0 "" ""))
1532		      (pc)))]
1533  ""
1534  "if (m88k_compare_reg == NULL_RTX)
1535     {
1536       emit_bcnd (GT, operands[0]);
1537       DONE;
1538     }
1539   operands[1] = m88k_compare_reg;")
1540
1541(define_expand "bgtu"
1542  [(set (pc)
1543	(if_then_else (gtu (match_dup 1) (const_int 0))
1544		      (label_ref (match_operand 0 "" ""))
1545		      (pc)))]
1546  ""
1547  "if (m88k_compare_reg == NULL_RTX)
1548     {
1549       emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1550       DONE;
1551     }
1552   operands[1] = m88k_compare_reg;")
1553
1554(define_expand "blt"
1555  [(set (pc)
1556	(if_then_else (lt (match_dup 1) (const_int 0))
1557		      (label_ref (match_operand 0 "" ""))
1558		      (pc)))]
1559  ""
1560  "if (m88k_compare_reg == NULL_RTX)
1561     {
1562       emit_bcnd (LT, operands[0]);
1563       DONE;
1564     }
1565   operands[1] = m88k_compare_reg;")
1566
1567(define_expand "bltu"
1568  [(set (pc)
1569	(if_then_else (ltu (match_dup 1) (const_int 0))
1570		      (label_ref (match_operand 0 "" ""))
1571		      (pc)))]
1572  ""
1573  "if (m88k_compare_reg == NULL_RTX)
1574     {
1575       emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1576       DONE;
1577     }
1578   operands[1] = m88k_compare_reg;")
1579
1580(define_expand "bge"
1581  [(set (pc)
1582	(if_then_else (ge (match_dup 1) (const_int 0))
1583		      (label_ref (match_operand 0 "" ""))
1584		      (pc)))]
1585  ""
1586  "if (m88k_compare_reg == NULL_RTX)
1587     {
1588       emit_bcnd (GE, operands[0]);
1589       DONE;
1590     }
1591   operands[1] = m88k_compare_reg;")
1592
1593(define_expand "bgeu"
1594  [(set (pc)
1595	(if_then_else (geu (match_dup 1) (const_int 0))
1596		      (label_ref (match_operand 0 "" ""))
1597		      (pc)))]
1598  ""
1599  "if (m88k_compare_reg == NULL_RTX)
1600     {
1601       emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1602       DONE;
1603     }
1604   operands[1] = m88k_compare_reg;")
1605
1606(define_expand "ble"
1607  [(set (pc)
1608	(if_then_else (le (match_dup 1) (const_int 0))
1609		      (label_ref (match_operand 0 "" ""))
1610		      (pc)))]
1611  ""
1612  "if (m88k_compare_reg == NULL_RTX)
1613     {
1614       emit_bcnd (LE, operands[0]);
1615       DONE;
1616     }
1617   operands[1] = m88k_compare_reg;")
1618
1619(define_expand "bleu"
1620  [(set (pc)
1621	(if_then_else (leu (match_dup 1) (const_int 0))
1622		      (label_ref (match_operand 0 "" ""))
1623		      (pc)))]
1624  ""
1625  "if (m88k_compare_reg == NULL_RTX)
1626     {
1627       emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1628       DONE;
1629     }
1630   operands[1] = m88k_compare_reg;")
1631
1632;; The actual conditional branch instruction (both directions).  This
1633;; uses two unusual template patterns, %Rx and %Px.  %Rx is a prefix code
1634;; for the immediately following condition and reverses the condition iff
1635;; operand `x' is a LABEL_REF.  %Px does nothing if `x' is PC and outputs
1636;; the operand if `x' is a LABEL_REF.
1637
1638(define_insn ""
1639  [(set (pc) (if_then_else
1640	      (match_operator 0 "relop"
1641			      [(match_operand:CC 1 "register_operand" "r")
1642			       (const_int 0)])
1643	      (match_operand 2 "pc_or_label_ref" "")
1644	      (match_operand 3 "pc_or_label_ref" "")))]
1645  ""
1646{
1647  if (mostly_false_jump (insn, operands[0]))
1648    return "bb0%. %R2%C0,%1,%P2%P3";
1649  else
1650    return "bb1%. %R3%C0,%1,%P2%P3";
1651}
1652  [(set_attr "type" "branch")])
1653
1654;;
1655;; Here branch prediction is sacrificed. To get it back, you need
1656;;  - CCODD (CC mode where the ODD bits are valid)
1657;;  - several define_split that can apply De Morgan's Law.
1658;;  - transformations between CCEVEN and CCODD modes.
1659;;
1660
1661(define_insn ""
1662  [(set (pc) (if_then_else
1663	      (match_operator 0 "even_relop"
1664			      [(match_operand:CCEVEN 1 "register_operand" "r")
1665			       (const_int 0)])
1666	      (match_operand 2 "pc_or_label_ref" "")
1667	      (match_operand 3 "pc_or_label_ref" "")))]
1668  ""
1669  "bb%L2%. %C0,%1,%P2%P3"
1670  [(set_attr "type" "branch")])
1671
1672(define_insn ""
1673  [(set (pc) (if_then_else
1674	      (match_operator 0 "odd_relop"
1675			      [(match_operand:CCEVEN 1 "register_operand" "r")
1676			       (const_int 0)])
1677	      (match_operand 2 "pc_or_label_ref" "")
1678	      (match_operand 3 "pc_or_label_ref" "")))]
1679  ""
1680  "bb%L3%. %!%C0,%1,%P2%P3"
1681  [(set_attr "type" "branch")])
1682
1683;; Branch conditional on scc values.  These arise from manipulations on
1684;; compare words above.
1685;; Are these really used ?
1686
1687(define_insn ""
1688  [(set (pc)
1689	(if_then_else
1690	 (ne (match_operator 0 "relop"
1691			     [(match_operand:CC 1 "register_operand" "r")
1692			      (const_int 0)])
1693	     (const_int 0))
1694	 (match_operand 2 "pc_or_label_ref" "")
1695	 (match_operand 3 "pc_or_label_ref" "")))]
1696  ""
1697  "bb%L2 %C0,%1,%P2%P3"
1698  [(set_attr "type" "branch")])
1699
1700(define_insn ""
1701  [(set (pc)
1702	(if_then_else
1703	 (ne (match_operator 0 "even_relop"
1704			     [(match_operand:CCEVEN 1 "register_operand" "r")
1705			      (const_int 0)])
1706	     (const_int 0))
1707	 (match_operand 2 "pc_or_label_ref" "")
1708	 (match_operand 3 "pc_or_label_ref" "")))]
1709  ""
1710  "bb%L2 %C0,%1,%P2%P3"
1711  [(set_attr "type" "branch")])
1712
1713(define_insn ""
1714  [(set (pc)
1715	(if_then_else
1716	 (ne (match_operator 0 "odd_relop"
1717			     [(match_operand:CCEVEN 1 "register_operand" "r")
1718			      (const_int 0)])
1719	     (const_int 0))
1720	 (match_operand 2 "pc_or_label_ref" "")
1721	 (match_operand 3 "pc_or_label_ref" "")))]
1722  ""
1723  "bb%L3 %!%C0,%1,%P2%P3"
1724  [(set_attr "type" "branch")])
1725
1726(define_insn ""
1727  [(set (pc)
1728	(if_then_else
1729	 (eq (match_operator 0 "relop"
1730			     [(match_operand:CC 1 "register_operand" "r")
1731			      (const_int 0)])
1732	     (const_int 0))
1733	 (match_operand 2 "pc_or_label_ref" "")
1734	 (match_operand 3 "pc_or_label_ref" "")))]
1735  ""
1736  "bb%L3 %C0,%1,%P2%P3"
1737  [(set_attr "type" "branch")])
1738
1739(define_insn ""
1740  [(set (pc)
1741	(if_then_else
1742	 (eq (match_operator 0 "even_relop"
1743			     [(match_operand:CCEVEN 1 "register_operand" "r")
1744			      (const_int 0)])
1745	     (const_int 0))
1746	 (match_operand 2 "pc_or_label_ref" "")
1747	 (match_operand 3 "pc_or_label_ref" "")))]
1748  ""
1749  "bb%L3 %C0,%1,%P2%P3"
1750  [(set_attr "type" "branch")])
1751
1752(define_insn ""
1753  [(set (pc)
1754	(if_then_else
1755	 (eq (match_operator 0 "odd_relop"
1756			     [(match_operand:CCEVEN 1 "register_operand" "r")
1757			      (const_int 0)])
1758	     (const_int 0))
1759	 (match_operand 2 "pc_or_label_ref" "")
1760	 (match_operand 3 "pc_or_label_ref" "")))]
1761  ""
1762  "bb%L2 %!%C0,%1,%P2%P3"
1763  [(set_attr "type" "branch")])
1764
1765(define_insn "locate1"
1766  [(set (match_operand:SI 0 "register_operand" "=r")
1767	(high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))]
1768  "flag_pic"
1769  "or.u %0,%#r0,%#hi16(%1#abdiff)")
1770
1771(define_insn "locate2"
1772  [(parallel [(set (reg:SI 1) (pc))
1773	      (set (match_operand:SI 0 "register_operand" "=r")
1774		   (lo_sum:SI (match_dup 0)
1775			      (unspec:SI
1776			       [(label_ref (match_operand 1 "" ""))] UNSPEC_ABDIFF)))])]
1777  "flag_pic"
1778  "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1779  [(set_attr "length" "2")])
1780
1781;; SImode move instructions
1782
1783(define_expand "movsi"
1784  [(set (match_operand:SI 0 "general_operand" "")
1785	(match_operand:SI 1 "general_operand" ""))]
1786  ""
1787  "
1788{
1789  if (emit_move_sequence (operands, SImode, NULL_RTX))
1790    DONE;
1791}")
1792
1793(define_expand "reload_insi"
1794  [(set (match_operand:SI 0 "register_operand" "=r")
1795	(match_operand:SI 1 "general_operand" ""))
1796   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1797  ""
1798  "
1799{
1800  if (emit_move_sequence (operands, SImode, operands[2]))
1801    DONE;
1802
1803  /* We don't want the clobber emitted, so handle this ourselves.  */
1804  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1805  DONE;
1806}")
1807
1808(define_insn ""
1809  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1810	(match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1811  "(register_operand (operands[0], SImode)
1812    || register_operand (operands[1], SImode)
1813    || operands[1] == const0_rtx)"
1814  "@
1815   or %0,%#r0,%1
1816   %V1ld\\t %0,%1
1817   %v0st\\t %r1,%0
1818   subu %0,%#r0,%n1
1819   set %0,%#r0,%s1
1820   mov.s %0,%1
1821   mov.s %0,%1
1822   mov %0,%1
1823   %V1ld\\t %0,%1
1824   %v0st\\t %1,%0"
1825  [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1826
1827(define_insn ""
1828  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1829	(match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1830  ""
1831  "@
1832   or %0,%#r0,%1
1833   subu %0,%#r0,%n1
1834   or.u %0,%#r0,%X1
1835   set %0,%#r0,%s1
1836   or.u %0,%#r0,%X1\;or %0,%0,%x1"
1837  [(set_attr "type" "arith,arith,arith,bit,marith")])
1838
1839;; @@ Why the constraint "in"?  Doesn't `i' include `n'?
1840(define_insn ""
1841  [(set (match_operand:SI 0 "register_operand" "=r")
1842	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1843		   (match_operand:SI 2 "immediate_operand" "in")))]
1844  ""
1845  "or %0,%1,%#lo16(%g2)")
1846
1847(define_insn ""
1848  [(set (match_operand:SI 0 "register_operand" "=r")
1849	(high:SI (match_operand 1 "" "")))]
1850  ""
1851  "or.u %0,%#r0,%#hi16(%g1)")
1852
1853;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1854;; confuse them with real addresses.
1855
1856(define_insn "movsi_lo_sum_pic"
1857  [(set (match_operand:SI 0 "register_operand" "=r")
1858	(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1859		   (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_GOT_REL)))]
1860  "flag_pic"
1861  "or %0,%1,%#lo16(%g2)"
1862  ;; Need to set length for this arith insn because operand2
1863  ;; is not an "arith_operand".
1864  [(set_attr "length" "1")])
1865
1866(define_insn "movsi_high_pic"
1867  [(set (match_operand:SI 0 "register_operand" "=r")
1868	(high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT_REL)))]
1869  "flag_pic"
1870  "or.u %0,%#r0,%#hi16(%g1)"
1871  ;; Need to set length for this arith insn because operand2
1872  ;; is not an arith_operand.
1873  [(set_attr "length" "1")])
1874
1875;; HImode move instructions
1876
1877(define_expand "movhi"
1878  [(set (match_operand:HI 0 "general_operand" "")
1879	(match_operand:HI 1 "general_operand" ""))]
1880  ""
1881  "
1882{
1883  if (emit_move_sequence (operands, HImode, NULL_RTX))
1884    DONE;
1885}")
1886
1887(define_insn ""
1888  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1889	(match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1890  "(register_operand (operands[0], HImode)
1891    || register_operand (operands[1], HImode)
1892    || operands[1] == const0_rtx)"
1893  "@
1894   or %0,%#r0,%h1
1895   %V1ld.hu\\t %0,%1
1896   %v0st.h\\t %r1,%0
1897   subu %0,%#r0,%H1"
1898  [(set_attr "type" "arith,load,store,arith")])
1899
1900(define_insn ""
1901  [(set (match_operand:HI 0 "register_operand" "=r")
1902	(subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1903			      (match_operand:SI 2 "immediate_operand" "in")) 0))]
1904  "!flag_pic"
1905  "or %0,%1,%#lo16(%2)")
1906
1907;; QImode move instructions
1908
1909(define_expand "movqi"
1910  [(set (match_operand:QI 0 "general_operand" "")
1911	(match_operand:QI 1 "general_operand" ""))]
1912  ""
1913  "
1914{
1915  if (emit_move_sequence (operands, QImode, NULL_RTX))
1916    DONE;
1917}")
1918
1919(define_insn ""
1920  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1921	(match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1922  "(register_operand (operands[0], QImode)
1923    || register_operand (operands[1], QImode)
1924    || operands[1] == const0_rtx)"
1925  "@
1926   or %0,%#r0,%q1
1927   %V1ld.bu\\t %0,%1
1928   %v0st.b\\t %r1,%0
1929   subu %0,%#r0,%Q1"
1930  [(set_attr "type" "arith,load,store,arith")])
1931
1932(define_insn ""
1933  [(set (match_operand:QI 0 "register_operand" "=r")
1934	(subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1935			      (match_operand:SI 2 "immediate_operand" "in")) 0))]
1936  "!flag_pic"
1937  "or %0,%1,%#lo16(%2)")
1938
1939;; DImode move instructions
1940
1941(define_expand "movdi"
1942  [(set (match_operand:DI 0 "general_operand" "")
1943	(match_operand:DI 1 "general_operand" ""))]
1944  ""
1945  "
1946{
1947  if (emit_move_sequence (operands, DImode, NULL_RTX))
1948    DONE;
1949}")
1950
1951(define_insn ""
1952  [(set (match_operand:DI 0 "register_operand" "=r,x")
1953	(const_int 0))]
1954  ""
1955  "@
1956   or %0,%#r0,0\;or %d0,%#r0,0
1957   mov %0,%#x0"
1958  [(set_attr "type" "marith,mov")])
1959
1960(define_insn ""
1961  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1962	(match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1963  ""
1964  "@
1965   or %0,%#r0,%1\;or %d0,%#r0,%d1
1966   %V1ld.d\\t %0,%1
1967   %v0st.d\\t %1,%0
1968   mov.d %0,%1
1969   mov.d %0,%1
1970   mov %0,%1
1971   %V1ld.d\\t %0,%1
1972   %v0st.d\\t %1,%0"
1973  [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1974
1975(define_insn ""
1976  [(set (match_operand:DI 0 "register_operand" "=r")
1977	(subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1978			      (match_operand:SI 2 "immediate_operand" "in")) 0))]
1979  "!flag_pic"
1980  "or %0,%1,%#lo16(%2)")
1981
1982(define_insn ""
1983  [(set (match_operand:DI 0 "register_operand" "=r")
1984	(match_operand:DI 1 "immediate_operand" "n"))]
1985   ""
1986   "* return output_load_const_dimode (operands);"
1987  [(set_attr "type" "marith")
1988   (set_attr "length" "4")]) ; length is 2, 3 or 4.
1989
1990;; DFmode move instructions
1991
1992(define_expand "movdf"
1993  [(set (match_operand:DF 0 "general_operand" "")
1994	(match_operand:DF 1 "general_operand" ""))]
1995  ""
1996  "
1997{
1998  if (emit_move_sequence (operands, DFmode, NULL_RTX))
1999    DONE;
2000}")
2001
2002(define_split
2003  [(set (match_operand:DF 0 "register_operand" "")
2004	(match_operand:DF 1 "register_operand" ""))]
2005  "reload_completed
2006   && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
2007   && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
2008  [(set (match_dup 2) (match_dup 3))
2009   (set (match_dup 4) (match_dup 5))]
2010  "
2011{ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2012  operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2013  operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2014  operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
2015
2016(define_insn ""
2017  [(set (match_operand:DF 0 "register_operand" "=r,x")
2018	(const_int 0))]
2019  ""
2020  "@
2021   or %0,%#r0,0\;or %d0,%#r0,0
2022   mov %0,%#x0"
2023  [(set_attr "type" "marith,mov")])
2024
2025(define_insn ""
2026  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2027	(match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2028  ""
2029  "@
2030   or %0,%#r0,%1\;or %d0,%#r0,%d1
2031   %V1ld.d\\t %0,%1
2032   %v0st.d\\t %1,%0
2033   mov.d %0,%1
2034   mov.d %0,%1
2035   mov %0,%1
2036   %V1ld.d\\t %0,%1
2037   %v0st.d\\t %1,%0"
2038  [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2039
2040(define_insn ""
2041  [(set (match_operand:DF 0 "register_operand" "=r")
2042	(subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2043			      (match_operand:SI 2 "immediate_operand" "in")) 0))]
2044  "!flag_pic"
2045  "or %0,%1,%#lo16(%2)")
2046
2047(define_insn ""
2048  [(set (match_operand:DF 0 "register_operand" "=r")
2049	(match_operand:DF 1 "immediate_operand" "F"))]
2050   ""
2051   "* return output_load_const_double (operands);"
2052  [(set_attr "type" "marith")
2053   (set_attr "length" "4")]) ; length is 2, 3, or 4.
2054
2055;; SFmode move instructions
2056
2057(define_expand "movsf"
2058  [(set (match_operand:SF 0 "general_operand" "")
2059	(match_operand:SF 1 "general_operand" ""))]
2060  ""
2061  "
2062{
2063  if (emit_move_sequence (operands, SFmode, NULL_RTX))
2064    DONE;
2065}")
2066
2067(define_insn ""
2068  [(set (match_operand:SF 0 "register_operand" "=r,x")
2069	(const_int 0))]
2070  ""
2071  "@
2072   or %0,%#r0,0
2073   mov %0,%#x0"
2074  [(set_attr "type" "arith,mov")])
2075
2076(define_insn ""
2077  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2078	(match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2079  ""
2080  "@
2081   or %0,%#r0,%1
2082   %V1ld\\t %0,%1
2083   %v0st\\t %r1,%0
2084   mov.s %0,%1
2085   mov.s %0,%1
2086   mov %0,%1
2087   %V1ld\\t %0,%1
2088   %v0st\\t %r1,%0"
2089  [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2090
2091(define_insn ""
2092  [(set (match_operand:SF 0 "register_operand" "=r")
2093	(subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2094			      (match_operand:SI 2 "immediate_operand" "in")) 0))]
2095  "!flag_pic"
2096  "or %0,%1,%#lo16(%2)")
2097
2098(define_insn ""
2099  [(set (match_operand:SF 0 "register_operand" "=r")
2100	(match_operand:SF 1 "immediate_operand" "F"))]
2101  "operands[1] != const0_rtx"
2102  "* return output_load_const_float (operands);"
2103  [(set_attr "type" "marith")]) ; length is 1 or 2.
2104
2105;; CCmode move instructions
2106
2107;; These are a subset of the SImode move instructions. They are necessary
2108;; because the reload pass may elect to store reg:CC registers in memory,
2109;; and read them back.
2110
2111(define_expand "movcc"
2112  [(set (match_operand:CC 0 "general_operand" "")
2113	(match_operand:CC 1 "general_operand" ""))]
2114  ""
2115  "
2116{
2117  if (emit_move_sequence (operands, CCmode, NULL_RTX))
2118    DONE;
2119}")
2120
2121(define_insn ""
2122  [(set (match_operand:CC 0 "nonimmediate_operand" "=r,r,m")
2123	(match_operand:CC 1 "move_operand" "rI,m,rO"))]
2124  "(register_operand (operands[0], CCmode)
2125    || register_operand (operands[1], CCmode)
2126    || operands[1] == const0_rtx)"
2127  "@
2128   or %0,%#r0,%1
2129   %V1ld\\t %0,%1
2130   %v0st\\t %r1,%0"
2131  [(set_attr "type" "arith,load,store")])
2132
2133
2134;; String/block move insn.  See m88k.c for details.
2135
2136(define_expand "movstrsi"
2137  [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2138		   (mem:BLK (match_operand:BLK 1 "" "")))
2139	      (use (match_operand:SI 2 "arith32_operand" ""))
2140	      (use (match_operand:SI 3 "immediate_operand" ""))])]
2141  ""
2142  "
2143{
2144  rtx dest_mem = operands[0];
2145  rtx src_mem = operands[1];
2146  operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2147  operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2148  expand_block_move (dest_mem, src_mem, operands);
2149  DONE;
2150}")
2151
2152;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2153;; operand 0 is the function name
2154;; operand 1 is the destination pointer
2155;; operand 2 is the source pointer
2156;; operand 3 is the offset for the source and destination pointers
2157;; operand 4 is the first value to be loaded
2158;; operand 5 is the register to hold the value (r4 or r5, or r4 or r6 if DImode)
2159
2160(define_expand "call_block_move"
2161  [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2162			     (match_operand:SI 3 "immediate_operand" "")))
2163   (set (match_operand 5 "register_operand" "")
2164	(match_operand 4 "memory_operand" ""))
2165   (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2166			     (match_dup 3)))
2167   (use (reg:SI 2))
2168   (use (reg:SI 3))
2169   (use (reg:SI 4))
2170   (use (reg:SI 5))
2171   (parallel [(set (reg:DI 2)
2172		   (call (mem:SI (match_operand 0 "" ""))
2173			 (const_int 0)))
2174	      (clobber (reg:SI 1))])]
2175  ""
2176  "")
2177
2178(define_expand "call_block_move_DI"
2179  [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2180			     (match_operand:SI 3 "immediate_operand" "")))
2181   (set (match_operand 5 "register_operand" "")
2182	(match_operand 4 "memory_operand" ""))
2183   (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2184			     (match_dup 3)))
2185   (use (reg:SI 2))
2186   (use (reg:SI 3))
2187   (use (reg:DI 4))
2188   (use (reg:DI 6))
2189   (parallel [(set (reg:DI 2)
2190		   (call (mem:SI (match_operand 0 "" ""))
2191			 (const_int 0)))
2192	      (clobber (reg:SI 1))])]
2193  ""
2194  "")
2195
2196;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2197;; operands 0-5 as in the non-looping interface
2198;; operand 6 is the loop count
2199
2200(define_expand "call_movstrsi_loop"
2201  [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2202			     (match_operand:SI 3 "immediate_operand" "")))
2203   (set (match_operand:SI 5 "register_operand" "")
2204	(match_operand 4 "memory_operand" ""))
2205   (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2206			     (match_dup 3)))
2207   (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2208   (use (reg:SI 2))
2209   (use (reg:SI 3))
2210   (use (match_dup 5))
2211   (use (reg:SI 6))
2212   (parallel [(set (reg:DI 2)
2213		   (call (mem:SI (match_operand 0 "" ""))
2214			 (const_int 0)))
2215	      (clobber (reg:SI 1))])]
2216  ""
2217  "")
2218
2219;;- zero extension instructions
2220
2221(define_expand "zero_extendhisi2"
2222  [(set (match_operand:SI 0 "register_operand" "")
2223	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2224  ""
2225  "
2226{
2227  if (GET_CODE (operands[1]) == MEM
2228      && symbolic_operand (XEXP (operands[1], 0), SImode))
2229    operands[1]
2230      = legitimize_address (flag_pic, operands[1], 0, 0);
2231}")
2232
2233(define_insn ""
2234  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2235	(zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2236  "GET_CODE (operands[1]) != CONST_INT"
2237  "@
2238   mask %0,%1,0xffff
2239   or %0,%#r0,%h1
2240   %V1ld.hu\\t %0,%1"
2241  [(set_attr "type" "arith,arith,load")])
2242
2243(define_expand "zero_extendqihi2"
2244  [(set (match_operand:HI 0 "register_operand" "")
2245	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2246  ""
2247  "
2248{
2249  if (GET_CODE (operands[1]) == MEM
2250      && symbolic_operand (XEXP (operands[1], 0), HImode))
2251    operands[1]
2252      = legitimize_address (flag_pic, operands[1], 0, 0);
2253}")
2254
2255(define_insn ""
2256  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2257	(zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2258  "GET_CODE (operands[1]) != CONST_INT"
2259  "@
2260   mask %0,%1,0xff
2261   or %0,%#r0,%q1
2262   %V1ld.bu\\t %0,%1"
2263  [(set_attr "type" "arith,arith,load")])
2264
2265(define_expand "zero_extendqisi2"
2266  [(set (match_operand:SI 0 "register_operand" "")
2267	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2268  ""
2269  "
2270{
2271  if (GET_CODE (operands[1]) == MEM
2272      && symbolic_operand (XEXP (operands[1], 0), SImode))
2273    {
2274      operands[1]
2275	= legitimize_address (flag_pic, operands[1], 0, 0);
2276      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2277			      gen_rtx_ZERO_EXTEND (SImode, operands[1])));
2278      DONE;
2279    }
2280}")
2281
2282(define_insn ""
2283  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2284	(zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2285  "GET_CODE (operands[1]) != CONST_INT"
2286  "@
2287   mask %0,%1,0xff
2288   or %0,%#r0,%q1
2289   %V1ld.bu\\t %0,%1"
2290  [(set_attr "type" "arith,arith,load")])
2291
2292;;- sign extension instructions
2293
2294(define_insn "extendsidi2"
2295  [(set (match_operand:DI 0 "register_operand" "=r")
2296	(sign_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2297  ""
2298  "#")
2299
2300(define_split
2301  [(set (match_operand:DI 0 "register_operand" "")
2302	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
2303  "reload_completed
2304   && GET_CODE (operands[0]) == REG
2305   && GET_CODE (operands[1]) == REG"
2306  [(set (subreg:SI (match_dup 0) 4) (match_dup 1))
2307   (set (subreg:SI (match_dup 0) 0)
2308	(ashiftrt:SI (match_dup 1) (const_int 31)))]
2309  "")
2310
2311(define_expand "extendhisi2"
2312  [(set (match_operand:SI 0 "register_operand" "")
2313	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2314  ""
2315  "
2316{
2317  if (GET_CODE (operands[1]) == MEM
2318      && symbolic_operand (XEXP (operands[1], 0), SImode))
2319    operands[1]
2320      = legitimize_address (flag_pic, operands[1], 0, 0);
2321}")
2322
2323(define_insn ""
2324  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2325	(sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2326  "GET_CODE (operands[1]) != CONST_INT"
2327  "@
2328   ext %0,%1,16<0>
2329   or %0,%#r0,%h1
2330   subu %0,%#r0,%H1
2331   %V1ld.h\\t %0,%1"
2332  [(set_attr "type" "bit,arith,arith,load")])
2333
2334(define_expand "extendqihi2"
2335  [(set (match_operand:HI 0 "register_operand" "")
2336	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2337  ""
2338  "
2339{
2340  if (GET_CODE (operands[1]) == MEM
2341      && symbolic_operand (XEXP (operands[1], 0), HImode))
2342    operands[1]
2343      = legitimize_address (flag_pic, operands[1], 0, 0);
2344}")
2345
2346(define_insn ""
2347  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2348	(sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2349  "GET_CODE (operands[1]) != CONST_INT"
2350  "@
2351   ext %0,%1,8<0>
2352   or %0,%#r0,%q1
2353   subu %0,%#r0,%Q1
2354   %V1ld.b\\t %0,%1"
2355  [(set_attr "type" "bit,arith,arith,load")])
2356
2357(define_expand "extendqisi2"
2358  [(set (match_operand:SI 0 "register_operand" "")
2359	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2360  ""
2361  "
2362{
2363  if (GET_CODE (operands[1]) == MEM
2364      && symbolic_operand (XEXP (operands[1], 0), SImode))
2365    operands[1]
2366      = legitimize_address (flag_pic, operands[1], 0, 0);
2367}")
2368
2369(define_insn ""
2370  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2371	(sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2372  "GET_CODE (operands[1]) != CONST_INT"
2373  "@
2374   ext %0,%1,8<0>
2375   or %0,%#r0,%q1
2376   subu %0,%#r0,%Q1
2377   %V1ld.b\\t %0,%1"
2378  [(set_attr "type" "bit,arith,arith,load")])
2379
2380;; Conversions between float and double.
2381
2382;; The fadd instruction does not conform to IEEE 754 when used to
2383;; convert between float and double.  In particular, the sign of -0 is
2384;; not preserved.  Interestingly, fsub does conform.
2385
2386(define_expand "extendsfdf2"
2387  [(set (match_operand:DF 0 "register_operand" "=r")
2388	(float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2389  ""
2390  "")
2391
2392(define_insn ""
2393  [(set (match_operand:DF 0 "register_operand" "=r")
2394	(float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2395  "! TARGET_88110"
2396  "fsub.dss %0,%1,%#r0"
2397  [(set_attr "type" "spadd")])
2398
2399(define_insn ""
2400  [(set (match_operand:DF 0 "register_operand" "=r,x")
2401	(float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2402  "TARGET_88110"
2403  "fcvt.ds %0,%1"
2404  [(set_attr "type" "spadd")])
2405
2406(define_expand "truncdfsf2"
2407  [(set (match_operand:SF 0 "register_operand" "=r")
2408	(float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2409  ""
2410  "")
2411
2412(define_insn ""
2413  [(set (match_operand:SF 0 "register_operand" "=r")
2414	(float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2415  "! TARGET_88110"
2416  "fsub.sds %0,%1,%#r0"
2417  [(set_attr "type" "dpadd")])
2418
2419(define_insn ""
2420  [(set (match_operand:SF 0 "register_operand" "=r,x")
2421	(float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2422  "TARGET_88110"
2423  "fcvt.sd %0,%1"
2424  [(set_attr "type" "dpadd")])
2425
2426;; Conversions between floating point and integer
2427
2428(define_insn "floatsidf2"
2429  [(set (match_operand:DF 0 "register_operand" "=r,x")
2430	(float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2431  ""
2432  "flt.ds %0,%1"
2433  [(set_attr "type" "spadd,dpadd")])
2434
2435(define_insn "floatsisf2"
2436  [(set (match_operand:SF 0 "register_operand" "=r,x")
2437	(float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2438  ""
2439  "flt.ss %0,%1"
2440  [(set_attr "type" "spadd,spadd")])
2441
2442(define_insn "fix_truncdfsi2"
2443  [(set (match_operand:SI 0 "register_operand" "=r,r")
2444	(fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2445  ""
2446  "trnc.sd %0,%1"
2447  [(set_attr "type" "dpadd,dpadd")])
2448
2449(define_insn "fix_truncsfsi2"
2450  [(set (match_operand:SI 0 "register_operand" "=r,r")
2451	(fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2452  ""
2453  "trnc.ss %0,%1"
2454  [(set_attr "type" "spadd,dpadd")])
2455
2456
2457;;- arithmetic instructions
2458;;- add instructions
2459
2460(define_insn "addsi3"
2461  [(set (match_operand:SI 0 "register_operand" "=r,r")
2462	(plus:SI (match_operand:SI 1 "arith32_operand" "%r,r")
2463		 (match_operand:SI 2 "arith32_operand" "rI,J")))]
2464  ""
2465  "@
2466   addu %0,%1,%2
2467   subu %0,%1,%n2")
2468
2469;; patterns for mixed mode floating point.
2470;; Do not define patterns that utilize mixed mode arithmetic that result
2471;; in narrowing the precision, because it loses accuracy, since the standard
2472;; requires double rounding, whereas the 88000 instruction only rounds once.
2473
2474(define_expand "adddf3"
2475  [(set (match_operand:DF 0 "register_operand" "=r,x")
2476	(plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2477		 (match_operand:DF 2 "general_operand" "r,x")))]
2478  ""
2479  "
2480{
2481  operands[1] = legitimize_operand (operands[1], DFmode);
2482  operands[2] = legitimize_operand (operands[2], DFmode);
2483}")
2484
2485(define_insn ""
2486  [(set (match_operand:DF 0 "register_operand" "=r,x")
2487	(plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2488		 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2489  ""
2490  "fadd.dss %0,%1,%2"
2491  [(set_attr "type" "spadd")])
2492
2493(define_insn ""
2494  [(set (match_operand:DF 0 "register_operand" "=r,x")
2495	(plus:DF (match_operand:DF 1 "register_operand" "r,x")
2496		 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2497  ""
2498  "fadd.dds %0,%1,%2"
2499  [(set_attr "type" "dpadd")])
2500
2501(define_insn ""
2502  [(set (match_operand:DF 0 "register_operand" "=r,x")
2503	(plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2504		 (match_operand:DF 2 "register_operand" "r,x")))]
2505  ""
2506  "fadd.dsd %0,%1,%2"
2507  [(set_attr "type" "dpadd")])
2508
2509(define_insn ""
2510  [(set (match_operand:DF 0 "register_operand" "=r,x")
2511	(plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2512		 (match_operand:DF 2 "register_operand" "r,x")))]
2513  ""
2514  "fadd.ddd %0,%1,%2"
2515  [(set_attr "type" "dpadd")])
2516
2517(define_insn "addsf3"
2518  [(set (match_operand:SF 0 "register_operand" "=r,x")
2519	(plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2520		 (match_operand:SF 2 "register_operand" "r,x")))]
2521  ""
2522  "fadd.sss %0,%1,%2"
2523  [(set_attr "type" "spadd")])
2524
2525(define_insn ""
2526  [(set (match_operand:DI 0 "register_operand" "=r")
2527	(plus:DI (match_operand:DI 1 "register_operand" "r")
2528		 (zero_extend:DI
2529		  (match_operand:SI 2 "register_operand" "r"))))
2530   (clobber (reg:CC 0))]
2531  ""
2532  "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2533  [(set_attr "type" "marith")])
2534
2535(define_insn ""
2536  [(set (match_operand:DI 0 "register_operand" "=r")
2537	(plus:DI (zero_extend:DI
2538		  (match_operand:SI 1 "register_operand" "r"))
2539		 (match_operand:DI 2 "register_operand" "r")))
2540   (clobber (reg:CC 0))]
2541  ""
2542  "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2543  [(set_attr "type" "marith")])
2544
2545(define_insn "adddi3"
2546  [(set (match_operand:DI 0 "register_operand" "=r")
2547	(plus:DI (match_operand:DI 1 "register_operand" "%r")
2548		 (match_operand:DI 2 "register_operand" "r")))
2549   (clobber (reg:CC 0))]
2550  ""
2551  "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2552  [(set_attr "type" "marith")])
2553
2554;; Add with carry insns.
2555
2556(define_insn ""
2557  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2558		   (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2559			    (match_operand:SI 2 "reg_or_0_operand" "rO")))
2560	      (set (reg:CC 0)
2561		   (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2562  ""
2563  "addu.co %0,%r1,%r2")
2564
2565(define_insn ""
2566  [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2567			       (match_operand:SI 1 "reg_or_0_operand" "rO")]
2568			      0))]
2569  ""
2570  "addu.co %#r0,%r0,%r1")
2571
2572(define_insn ""
2573  [(set (match_operand:SI 0 "register_operand" "=r")
2574	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2575		 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2576			     (reg:CC 0)] 0)))]
2577  ""
2578  "addu.ci %0,%r1,%r2")
2579
2580;;- subtract instructions
2581
2582(define_insn "subsi3"
2583  [(set (match_operand:SI 0 "register_operand" "=r")
2584	(minus:SI (match_operand:SI 1 "register_operand" "r")
2585		  (match_operand:SI 2 "arith32_operand" "rI")))]
2586  ""
2587  "subu %0,%1,%2")
2588
2589;; patterns for mixed mode floating point
2590;; Do not define patterns that utilize mixed mode arithmetic that result
2591;; in narrowing the precision, because it loses accuracy, since the standard
2592;; requires double rounding, whereas the 88000 instruction only rounds once.
2593
2594(define_expand "subdf3"
2595  [(set (match_operand:DF 0 "register_operand" "=r,x")
2596	(minus:DF (match_operand:DF 1 "general_operand" "r,x")
2597		  (match_operand:DF 2 "general_operand" "r,x")))]
2598  ""
2599  "
2600{
2601  operands[1] = legitimize_operand (operands[1], DFmode);
2602  operands[2] = legitimize_operand (operands[2], DFmode);
2603}")
2604
2605(define_insn ""
2606  [(set (match_operand:DF 0 "register_operand" "=r,x")
2607	(minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2608		  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2609  ""
2610  "fsub.dss %0,%1,%2"
2611  [(set_attr "type" "spadd")])
2612
2613(define_insn ""
2614  [(set (match_operand:DF 0 "register_operand" "=r,x")
2615	(minus:DF (match_operand:DF 1 "register_operand" "r,x")
2616		  (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2617  ""
2618  "fsub.dds %0,%1,%2"
2619  [(set_attr "type" "dpadd")])
2620
2621(define_insn ""
2622  [(set (match_operand:DF 0 "register_operand" "=r,x")
2623	(minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2624		  (match_operand:DF 2 "register_operand" "r,x")))]
2625  ""
2626  "fsub.dsd %0,%1,%2"
2627  [(set_attr "type" "dpadd")])
2628
2629(define_insn ""
2630  [(set (match_operand:DF 0 "register_operand" "=r,x")
2631	(minus:DF (match_operand:DF 1 "register_operand" "r,x")
2632		  (match_operand:DF 2 "register_operand" "r,x")))]
2633  ""
2634  "fsub.ddd %0,%1,%2"
2635  [(set_attr "type" "dpadd")])
2636
2637(define_insn "subsf3"
2638  [(set (match_operand:SF 0 "register_operand" "=r,x")
2639	(minus:SF (match_operand:SF 1 "register_operand" "r,x")
2640		  (match_operand:SF 2 "register_operand" "r,x")))]
2641  ""
2642  "fsub.sss %0,%1,%2"
2643  [(set_attr "type" "spadd")])
2644
2645(define_insn ""
2646  [(set (match_operand:DI 0 "register_operand" "=r")
2647	(minus:DI (match_operand:DI 1 "register_operand" "r")
2648		  (zero_extend:DI
2649		   (match_operand:SI 2 "register_operand" "r"))))
2650   (clobber (reg:CC 0))]
2651  ""
2652  "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2653  [(set_attr "type" "marith")])
2654
2655(define_insn ""
2656  [(set (match_operand:DI 0 "register_operand" "=r")
2657	(minus:DI (zero_extend:DI
2658		   (match_operand:SI 1 "register_operand" "r"))
2659		  (match_operand:DI 2 "register_operand" "r")))
2660   (clobber (reg:CC 0))]
2661  ""
2662  "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2663  [(set_attr "type" "marith")])
2664
2665(define_insn "subdi3"
2666  [(set (match_operand:DI 0 "register_operand" "=r")
2667	(minus:DI (match_operand:DI 1 "register_operand" "r")
2668		  (match_operand:DI 2 "register_operand" "r")))
2669   (clobber (reg:CC 0))]
2670  ""
2671  "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2672  [(set_attr "type" "marith")])
2673
2674;; Subtract with carry insns.
2675
2676(define_insn ""
2677  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2678		   (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2679			     (match_operand:SI 2 "reg_or_0_operand" "rO")))
2680	      (set (reg:CC 0)
2681		   (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2682  ""
2683  "subu.co %0,%r1,%r2")
2684
2685(define_insn ""
2686  [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2687			       (match_operand:SI 1 "reg_or_0_operand" "rO")]
2688			      1))]
2689  ""
2690  "subu.co %#r0,%r0,%r1")
2691
2692(define_insn ""
2693  [(set (match_operand:SI 0 "register_operand" "=r")
2694	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2695		  (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2696			      (reg:CC 0)] 1)))]
2697  ""
2698  "subu.ci %0,%r1,%r2")
2699
2700;;- multiply instructions
2701;;
2702;; There is an unfounded silicon errata for E.1 requiring that an
2703;; immediate constant value in div/divu/mul instructions be less than
2704;; 0x800.  This is no longer provided for.
2705
2706(define_insn "mulsi3"
2707  [(set (match_operand:SI 0 "register_operand" "=r")
2708	(mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2709		 (match_operand:SI 2 "arith32_operand" "rI")))]
2710  ""
2711  "mul %0,%1,%2"
2712  [(set_attr "type" "imul")])
2713
2714(define_insn "umulsidi3"
2715  [(set (match_operand:DI 0 "register_operand" "=r")
2716        (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2717                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2718  "TARGET_88110"
2719  "mulu.d %0,%1,%2"
2720  [(set_attr "type" "imul")])
2721
2722;; patterns for mixed mode floating point
2723;; Do not define patterns that utilize mixed mode arithmetic that result
2724;; in narrowing the precision, because it loses accuracy, since the standard
2725;; requires double rounding, whereas the 88000 instruction only rounds once.
2726
2727(define_expand "muldf3"
2728  [(set (match_operand:DF 0 "register_operand" "=r,x")
2729	(mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2730		 (match_operand:DF 2 "general_operand" "r,x")))]
2731  ""
2732  "
2733{
2734  operands[1] = legitimize_operand (operands[1], DFmode);
2735  operands[2] = legitimize_operand (operands[2], DFmode);
2736}")
2737
2738(define_insn ""
2739  [(set (match_operand:DF 0 "register_operand" "=r,x")
2740	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2741		 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2742  ""
2743  "fmul.dss %0,%1,%2"
2744  [(set_attr "type" "spmul")])
2745
2746(define_insn ""
2747  [(set (match_operand:DF 0 "register_operand" "=r,x")
2748	(mult:DF (match_operand:DF 1 "register_operand" "r,x")
2749		 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2750  ""
2751  "fmul.dds %0,%1,%2"
2752  [(set_attr "type" "spmul")])
2753
2754(define_insn ""
2755  [(set (match_operand:DF 0 "register_operand" "=r,x")
2756	(mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2757		 (match_operand:DF 2 "register_operand" "r,x")))]
2758  ""
2759  "fmul.dsd %0,%1,%2"
2760  [(set_attr "type" "spmul")])
2761
2762(define_insn ""
2763  [(set (match_operand:DF 0 "register_operand" "=r,x")
2764	(mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2765		 (match_operand:DF 2 "register_operand" "r,x")))]
2766  ""
2767  "fmul.ddd %0,%1,%2"
2768  [(set_attr "type" "dpmul")])
2769
2770(define_insn "mulsf3"
2771  [(set (match_operand:SF 0 "register_operand" "=r,x")
2772	(mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2773		 (match_operand:SF 2 "register_operand" "r,x")))]
2774  ""
2775  "fmul.sss %0,%1,%2"
2776  [(set_attr "type" "spmul")])
2777
2778;;- divide instructions
2779;;
2780;; The 88k div and divu instructions don't reliably trap on
2781;; divide-by-zero.  A trap to vector 503 asserts divide-by-zero.  The
2782;; general scheme for doing divide is to do a 4-way split based on the
2783;; sign of the two operand and do the appropriate negates.
2784;;
2785;; The conditional trap instruction is not used as this serializes the
2786;; processor.  Instead a conditional branch and an unconditional trap
2787;; are used, but after the divu.  Since the divu takes up to 38 cycles,
2788;; the conditional branch is essentially free.
2789;;
2790;; Two target options control how divide is done.  One options selects
2791;; whether to do the branch and negate scheme instead of using the div
2792;; instruction; the other option selects whether to explicitly check
2793;; for divide-by-zero or take your chances.  If the div instruction is
2794;; used, the O/S must complete the operation if the operands are
2795;; negative.  The O/S will signal an overflow condition if the most
2796;; negative number (-2147483648) is divided by negative 1.
2797;;
2798;; There is an unfounded silicon errata for E.1 requiring that an
2799;; immediate constant value in div/divu/mul instructions be less than
2800;; 0x800.  This is no longer provided for.
2801
2802;; Division by 0 trap
2803(define_insn "trap_divide_by_zero"
2804  [(trap_if (const_int 1) (const_int 503))]
2805  ""
2806  "tb0 0,%#r0,503"
2807  [(set_attr "type" "weird")
2808   (set_attr "length" "1")])
2809
2810;; Conditional division by 0 trap.
2811(define_expand "tcnd_divide_by_zero"
2812  [(set (pc)
2813	(if_then_else (eq (match_operand:SI 0 "register_operand" "")
2814			  (const_int 0))
2815		      (pc)
2816		      (match_operand 1 "" "")))
2817   (trap_if (const_int 1) (const_int 503))]
2818  ""
2819  "
2820{
2821  emit_insn (gen_cmpsi (operands[0], const0_rtx));
2822  emit_jump_insn (gen_bne (operands[1]));
2823  emit_insn (gen_trap_divide_by_zero ());
2824  DONE;
2825}")
2826
2827(define_expand "divsi3"
2828  [(set (match_operand:SI 0 "register_operand" "")
2829	(div:SI (match_operand:SI 1 "arith32_operand" "")
2830		(match_operand:SI 2 "arith32_operand" "")))]
2831  ""
2832  "
2833{
2834  rtx op0 = operands[0];
2835  rtx op1 = operands[1];
2836  rtx op2 = operands[2];
2837  rtx join_label;
2838
2839  /* @@ This needs to be reworked.  Torbjorn Granlund has suggested making
2840     it a runtime (perhaps quite special).  */
2841
2842  if (GET_CODE (op1) == CONST_INT)
2843    op1 = force_reg (SImode, op1);
2844
2845  else if (GET_CODE (op2) == CONST_INT
2846	   && ! SMALL_INT (operands[2]))
2847    op2 = force_reg (SImode, op2);
2848
2849  if (op2 == const0_rtx)
2850    {
2851      emit_insn (gen_trap_divide_by_zero ());
2852      emit_insn (gen_dummy (op0));
2853      DONE;
2854    }
2855
2856  if (TARGET_USE_DIV)
2857    {
2858      emit_move_insn (op0, gen_rtx_DIV (SImode, op1, op2));
2859      if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2860	{
2861	  rtx label = gen_label_rtx ();
2862	  emit_insn (gen_tcnd_divide_by_zero (op2, label));
2863	  emit_label (label);
2864	  emit_insn (gen_dummy (op0));
2865	}
2866      DONE;
2867    }
2868
2869  join_label = gen_label_rtx ();
2870  if (GET_CODE (op1) == CONST_INT)
2871    {
2872      int neg = FALSE;
2873      rtx neg_op2 = gen_reg_rtx (SImode);
2874      rtx label1 = gen_label_rtx ();
2875
2876      if (INTVAL (op1) < 0)
2877	{
2878	  neg = TRUE;
2879	  op1 = GEN_INT (-INTVAL (op1));
2880	}
2881      op1 = force_reg (SImode, op1);
2882
2883      emit_insn (gen_negsi2 (neg_op2, op2));
2884      emit_insn (gen_cmpsi (op2, const0_rtx));
2885      emit_jump_insn (gen_bgt (label1));
2886						/* constant / 0-or-negative */
2887      emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2888      if (!neg)
2889	emit_insn (gen_negsi2 (op0, op0));
2890
2891      if (TARGET_CHECK_ZERO_DIV)
2892	emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2893      emit_jump_insn (gen_jump (join_label));
2894      emit_barrier ();
2895
2896      emit_label (label1);			/* constant / positive */
2897      emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2898      if (neg)
2899	emit_insn (gen_negsi2 (op0, op0));
2900    }
2901
2902  else if (GET_CODE (op2) == CONST_INT)
2903    {
2904      int neg = FALSE;
2905      rtx neg_op1 = gen_reg_rtx (SImode);
2906      rtx label1 = gen_label_rtx ();
2907
2908      if (INTVAL (op2) < 0)
2909	{
2910	  neg = TRUE;
2911	  op2 = GEN_INT (-INTVAL (op2));
2912	}
2913      else if (! SMALL_INT (operands[2]))
2914	op2 = force_reg (SImode, op2);
2915
2916      emit_insn (gen_negsi2 (neg_op1, op1));
2917      emit_insn (gen_cmpsi (op1, const0_rtx));
2918      emit_jump_insn (gen_bge (label1));
2919						/* 0-or-negative / constant */
2920      emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2921      if (!neg)
2922	emit_insn (gen_negsi2 (op0, op0));
2923
2924      emit_jump_insn (gen_jump (join_label));
2925      emit_barrier ();
2926
2927      emit_label (label1);			/* positive / constant */
2928      emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2929      if (neg)
2930	emit_insn (gen_negsi2 (op0, op0));
2931    }
2932
2933  else
2934    {
2935      rtx neg_op1 = gen_reg_rtx (SImode);
2936      rtx neg_op2 = gen_reg_rtx (SImode);
2937      rtx label1 = gen_label_rtx ();
2938      rtx label2 = gen_label_rtx ();
2939      rtx label3 = gen_label_rtx ();
2940      rtx label4 = NULL_RTX;
2941
2942      emit_insn (gen_negsi2 (neg_op2, op2));
2943      emit_insn (gen_cmpsi (op2, const0_rtx));
2944      emit_jump_insn (gen_bgt (label1));
2945
2946      emit_insn (gen_negsi2 (neg_op1, op1));
2947      emit_insn (gen_cmpsi (op1, const0_rtx));
2948      emit_jump_insn (gen_bge (label2));
2949						/* negative / negative-or-0 */
2950      emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, neg_op2));
2951
2952      if (TARGET_CHECK_ZERO_DIV)
2953	{
2954	  label4 = gen_label_rtx ();
2955	  emit_insn (gen_cmpsi (op2, const0_rtx));
2956	  emit_jump_insn (gen_bne (join_label));
2957	  emit_label (label4);
2958	  emit_insn (gen_trap_divide_by_zero ());
2959	}
2960      emit_jump_insn (gen_jump (join_label));
2961      emit_barrier ();
2962
2963      emit_label (label2);			/* pos.-or-0 / neg.-or-0 */
2964      emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2965
2966      if (TARGET_CHECK_ZERO_DIV)
2967	{
2968	  emit_insn (gen_cmpsi (op2, const0_rtx));
2969	  emit_jump_insn (gen_beq (label4));
2970	}
2971
2972      emit_insn (gen_negsi2 (op0, op0));
2973      emit_jump_insn (gen_jump (join_label));
2974      emit_barrier ();
2975
2976      emit_label (label1);
2977      emit_insn (gen_negsi2 (neg_op1, op1));
2978      emit_insn (gen_cmpsi (op1, const0_rtx));
2979      emit_jump_insn (gen_bge (label3));
2980						/* negative / positive */
2981      emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2982      emit_insn (gen_negsi2 (op0, op0));
2983      emit_jump_insn (gen_jump (join_label));
2984      emit_barrier ();
2985
2986      emit_label (label3);			/* positive-or-0 / positive */
2987      emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2988    }
2989
2990  emit_label (join_label);
2991
2992  emit_insn (gen_dummy (op0));
2993  DONE;
2994}")
2995
2996(define_insn ""
2997  [(set (match_operand:SI 0 "register_operand" "=r")
2998	(div:SI (match_operand:SI 1 "register_operand" "r")
2999		(match_operand:SI 2 "arith_operand" "rI")))]
3000  ""
3001  "div %0,%1,%2"
3002  [(set_attr "type" "idiv")])
3003
3004(define_expand "udivsi3"
3005  [(set (match_operand:SI 0 "register_operand" "")
3006	(udiv:SI (match_operand:SI 1 "register_operand" "")
3007		 (match_operand:SI 2 "arith32_operand" "")))]
3008  ""
3009  "
3010{
3011  rtx op2 = operands[2];
3012
3013  if (op2 == const0_rtx)
3014    {
3015      emit_insn (gen_trap_divide_by_zero ());
3016      emit_insn (gen_dummy (operands[0]));
3017      DONE;
3018    }
3019  else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3020    {
3021      rtx label = gen_label_rtx ();
3022      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3023			      gen_rtx_UDIV (SImode, operands[1], op2)));
3024      emit_insn (gen_tcnd_divide_by_zero (op2, label));
3025      emit_label (label);
3026      emit_insn (gen_dummy (operands[0]));
3027      DONE;
3028    }
3029}")
3030
3031(define_insn ""
3032 [(set (match_operand:SI 0 "register_operand" "=r")
3033       (udiv:SI (match_operand:SI 1 "register_operand" "r")
3034		(match_operand:SI 2 "arith32_operand" "rI")))]
3035  "operands[2] != const0_rtx"
3036  "divu %0,%1,%2"
3037  [(set_attr "type" "idiv")])
3038
3039(define_insn ""
3040 [(set (match_operand:SI 0 "register_operand" "=r")
3041       (udiv:SI (match_operand:SI 1 "register_operand" "r")
3042		(const_int 0)))]
3043  ""
3044  "tb0 0,%#r0,503"
3045  [(set_attr "type" "weird")
3046   (set_attr "length" "1")])
3047
3048;; patterns for mixed mode floating point.
3049;; Do not define patterns that utilize mixed mode arithmetic that result
3050;; in narrowing the precision, because it loses accuracy, since the standard
3051;; requires double rounding, whereas the 88000 instruction only rounds once.
3052
3053(define_expand "divdf3"
3054  [(set (match_operand:DF 0 "register_operand" "=r,x")
3055	(div:DF (match_operand:DF 1 "general_operand" "r,x")
3056		(match_operand:DF 2 "general_operand" "r,x")))]
3057  ""
3058  "
3059{
3060  operands[1] = legitimize_operand (operands[1], DFmode);
3061  if (real_power_of_2_operand (operands[2]))
3062    {
3063      REAL_VALUE_TYPE r;
3064      REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3065      bool result;
3066
3067      result = exact_real_inverse (DFmode, &r);
3068      gcc_assert (result);
3069      emit_insn (gen_muldf3 (operands[0], operands[1],
3070			     CONST_DOUBLE_FROM_REAL_VALUE (r, DFmode)));
3071      DONE;
3072    }
3073  else if (! register_operand (operands[2], DFmode))
3074    operands[2] = force_reg (DFmode, operands[2]);
3075}")
3076
3077(define_insn ""
3078  [(set (match_operand:DF 0 "register_operand" "=r,x")
3079	(div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3080		(float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3081  ""
3082  "fdiv.dss %0,%1,%2"
3083  [(set_attr "type" "dpdiv")])
3084
3085(define_insn ""
3086  [(set (match_operand:DF 0 "register_operand" "=r,x")
3087	(div:DF (match_operand:DF 1 "register_operand" "r,x")
3088		(float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3089  ""
3090  "fdiv.dds %0,%1,%2"
3091  [(set_attr "type" "dpdiv")])
3092
3093(define_insn ""
3094  [(set (match_operand:DF 0 "register_operand" "=r,x")
3095	(div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3096		(match_operand:DF 2 "register_operand" "r,x")))]
3097  ""
3098  "fdiv.dsd %0,%1,%2"
3099  [(set_attr "type" "dpdiv")])
3100
3101(define_insn "divsf3"
3102  [(set (match_operand:SF 0 "register_operand" "=r,x")
3103	(div:SF (match_operand:SF 1 "register_operand" "r,x")
3104		(match_operand:SF 2 "register_operand" "r,x")))]
3105  ""
3106  "fdiv.sss %0,%1,%2"
3107  [(set_attr "type" "spdiv")])
3108
3109(define_insn ""
3110  [(set (match_operand:DF 0 "register_operand" "=r,x")
3111	(div:DF (match_operand:DF 1 "register_operand" "r,x")
3112		(match_operand:DF 2 "register_operand" "r,x")))]
3113  ""
3114  "fdiv.ddd %0,%1,%2"
3115  [(set_attr "type" "dpdiv")])
3116
3117;; - remainder instructions, don't define, since the hardware doesn't have any
3118;; direct support, and GNU can synthesis them out of div/mul just fine.
3119
3120;;- load effective address, must come after add, so that we favor using
3121;;  addu reg,reg,reg  instead of:  lda reg,reg,reg (addu doesn't require
3122;;  the data unit), and also future 88k chips might not support unscaled
3123;;  lda instructions.
3124
3125(define_insn ""
3126  [(set (match_operand:SI 0 "register_operand" "=r")
3127	(match_operand:HI 1 "address_operand" "p"))]
3128  ""
3129  "lda.h %0,%a1"
3130  [(set_attr "type" "loada")])
3131
3132(define_insn ""
3133  [(set (match_operand:SI 0 "register_operand" "=r")
3134	(match_operand:SI 1 "address_operand" "p"))]
3135  ""
3136  "lda %0,%a1"
3137  [(set_attr "type" "loada")])
3138
3139(define_insn ""
3140  [(set (match_operand:SI 0 "register_operand" "=r")
3141	(match_operand:DI 1 "address_operand" "p"))]
3142  ""
3143  "lda.d %0,%a1"
3144  [(set_attr "type" "loada")])
3145
3146(define_insn ""
3147  [(set (match_operand:SI 0 "register_operand" "=r")
3148	(match_operand:SF 1 "address_operand" "p"))]
3149  ""
3150  "lda %0,%a1"
3151  [(set_attr "type" "loada")])
3152
3153(define_insn ""
3154  [(set (match_operand:SI 0 "register_operand" "=r")
3155	(match_operand:DF 1 "address_operand" "p"))]
3156  ""
3157  "lda.d %0,%a1"
3158  [(set_attr "type" "loada")])
3159
3160;;- and instructions (with complement also)
3161(define_insn ""
3162  [(set (match_operand:SI 0 "register_operand" "=r")
3163	(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3164		(match_operand:SI 2 "register_operand" "r")))]
3165  ""
3166  "and.c %0,%2,%1")
3167
3168;; If the operation is being performed on a 32-bit constant such that
3169;; it cannot be done in one insn, do it in two.  We may lose a bit on
3170;; CSE in pathological cases, but it seems better doing it this way.
3171
3172(define_expand "andsi3"
3173  [(set (match_operand:SI 0 "register_operand" "")
3174	(and:SI (match_operand:SI 1 "arith32_operand" "")
3175		(match_operand:SI 2 "arith32_operand" "")))]
3176  ""
3177  "
3178{
3179  if (GET_CODE (operands[2]) == CONST_INT)
3180    {
3181      int value = INTVAL (operands[2]);
3182
3183      if (! (SMALL_INTVAL (value)
3184	     || (value & 0xffff0000) == 0xffff0000
3185	     || (value & 0xffff) == 0xffff
3186	     || (value & 0xffff) == 0
3187	     || integer_ok_for_set (~value)))
3188	{
3189	  emit_insn (gen_andsi3 (operands[0], operands[1],
3190				 GEN_INT (value | 0xffff)));
3191	  operands[1] = operands[0];
3192	  operands[2] = GEN_INT (value | 0xffff0000);
3193	}
3194    }
3195}")
3196
3197(define_insn ""
3198  [(set (match_operand:SI 0 "register_operand" "=r,r")
3199	(and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3200		(match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3201  ""
3202  "* return output_and (operands);"
3203  [(set_attr "type" "arith,marith")])
3204
3205(define_insn ""
3206  [(set (match_operand:DI 0 "register_operand" "=r")
3207	(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3208		(match_operand:DI 2 "register_operand" "r")))]
3209  ""
3210  "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3211  [(set_attr "type" "marith")])
3212
3213(define_insn "anddi3"
3214  [(set (match_operand:DI 0 "register_operand" "=r")
3215	(and:DI (match_operand:DI 1 "arith64_operand" "%r")
3216		(match_operand:DI 2 "arith64_operand" "rn")))]
3217  ""
3218{
3219  rtx xoperands[10];
3220
3221  xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3222  xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3223  xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3224
3225  output_asm_insn (output_and (xoperands), xoperands);
3226
3227  operands[0] = operand_subword (operands[0], 0, 0, DImode);
3228  operands[1] = operand_subword (operands[1], 0, 0, DImode);
3229  operands[2] = operand_subword (operands[2], 0, 0, DImode);
3230
3231  return output_and (operands);
3232}
3233  [(set_attr "type" "marith")
3234   (set_attr "length" "4")]) ; length is 2, 3, or 4.
3235
3236;;- Bit set (inclusive or) instructions (with complement also)
3237(define_insn ""
3238  [(set (match_operand:SI 0 "register_operand" "=r")
3239	(ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3240		(match_operand:SI 2 "register_operand" "r")))]
3241  ""
3242  "or.c %0,%2,%1")
3243
3244(define_expand "iorsi3"
3245  [(set (match_operand:SI 0 "register_operand" "")
3246	(ior:SI (match_operand:SI 1 "arith32_operand" "")
3247		(match_operand:SI 2 "arith32_operand" "")))]
3248  ""
3249  "
3250{
3251  if (GET_CODE (operands[2]) == CONST_INT)
3252    {
3253      int value = INTVAL (operands[2]);
3254
3255      if (! (SMALL_INTVAL (value)
3256	     || (value & 0xffff) == 0
3257	     || integer_ok_for_set (value)))
3258	{
3259	  emit_insn (gen_iorsi3 (operands[0], operands[1],
3260				 GEN_INT (value & 0xffff0000)));
3261	  operands[1] = operands[0];
3262	  operands[2] = GEN_INT (value & 0xffff);
3263	}
3264    }
3265}")
3266
3267(define_insn ""
3268  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3269	(ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3270		(match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3271  ""
3272  "@
3273   or %0,%1,%2
3274   or.u %0,%1,%X2
3275   set %0,%1,%s2
3276   or.u %0,%1,%X2\;or %0,%0,%x2"
3277  [(set_attr "type" "arith,arith,bit,marith")])
3278
3279(define_insn ""
3280  [(set (match_operand:DI 0 "register_operand" "=r")
3281	(ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3282		(match_operand:DI 2 "register_operand" "r")))]
3283  ""
3284  "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3285  [(set_attr "type" "marith")])
3286
3287(define_insn "iordi3"
3288  [(set (match_operand:DI 0 "register_operand" "=r")
3289	(ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3290		(match_operand:DI 2 "arith64_operand" "rn")))]
3291  ""
3292{
3293  rtx xoperands[10];
3294
3295  xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3296  xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3297  xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3298
3299  output_asm_insn (output_ior (xoperands), xoperands);
3300
3301  operands[0] = operand_subword (operands[0], 0, 0, DImode);
3302  operands[1] = operand_subword (operands[1], 0, 0, DImode);
3303  operands[2] = operand_subword (operands[2], 0, 0, DImode);
3304
3305  return output_ior (operands);
3306}
3307  [(set_attr "type" "marith")
3308   (set_attr "length" "4")]) ; length is 2, 3, or 4.
3309
3310;;- xor instructions (with complement also)
3311(define_insn ""
3312  [(set (match_operand:SI 0 "register_operand" "=r")
3313	(not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3314			(match_operand:SI 2 "register_operand" "r"))))]
3315  ""
3316  "xor.c %0,%1,%2")
3317
3318(define_expand "xorsi3"
3319  [(set (match_operand:SI 0 "register_operand" "")
3320	(xor:SI (match_operand:SI 1 "arith32_operand" "")
3321		(match_operand:SI 2 "arith32_operand" "")))]
3322  ""
3323  "
3324{
3325  if (GET_CODE (operands[2]) == CONST_INT)
3326    {
3327      int value = INTVAL (operands[2]);
3328
3329      if (! (SMALL_INTVAL (value)
3330	     || (value & 0xffff) == 0))
3331	{
3332	  emit_insn (gen_xorsi3 (operands[0], operands[1],
3333				 GEN_INT (value & 0xffff0000)));
3334	  operands[1] = operands[0];
3335	  operands[2] = GEN_INT (value & 0xffff);
3336	}
3337    }
3338}")
3339
3340(define_insn ""
3341  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3342	(xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3343		(match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3344  ""
3345  "@
3346   xor %0,%1,%2
3347   xor.u %0,%1,%X2
3348   xor.u %0,%1,%X2\;xor %0,%0,%x2"
3349  [(set_attr "type" "arith,arith,marith")])
3350
3351(define_insn ""
3352  [(set (match_operand:DI 0 "register_operand" "=r")
3353	(not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3354			(match_operand:DI 2 "register_operand" "r"))))]
3355  ""
3356  "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3357  [(set_attr "type" "marith")])
3358
3359(define_insn "xordi3"
3360  [(set (match_operand:DI 0 "register_operand" "=r")
3361	(xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3362		(match_operand:DI 2 "arith64_operand" "rn")))]
3363  ""
3364{
3365  rtx xoperands[10];
3366
3367  xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3368  xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3369  xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3370
3371  output_asm_insn (output_xor (xoperands), xoperands);
3372
3373  operands[0] = operand_subword (operands[0], 0, 0, DImode);
3374  operands[1] = operand_subword (operands[1], 0, 0, DImode);
3375  operands[2] = operand_subword (operands[2], 0, 0, DImode);
3376
3377  return output_xor (operands);
3378}
3379  [(set_attr "type" "marith")
3380   (set_attr "length" "4")]) ; length is 2, 3, or 4.
3381
3382;;- ones complement instructions
3383(define_insn "one_cmplsi2"
3384  [(set (match_operand:SI 0 "register_operand" "=r")
3385	(not:SI (match_operand:SI 1 "register_operand" "r")))]
3386  ""
3387  "xor.c %0,%1,%#r0")
3388
3389(define_insn "one_cmpldi2"
3390  [(set (match_operand:DI 0 "register_operand" "=r")
3391	(not:DI (match_operand:DI 1 "register_operand" "r")))]
3392  ""
3393  "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3394  [(set_attr "type" "marith")])
3395
3396;; Optimized special cases of shifting.
3397;; Must precede the general case.
3398
3399;; @@ What about HImode shifted by 8?
3400
3401(define_insn ""
3402  [(set (match_operand:SI 0 "register_operand" "=r")
3403	(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3404		     (const_int 24)))]
3405  "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3406  "%V1ld.b\\t %0,%1"
3407  [(set_attr "type" "load")])
3408
3409(define_insn ""
3410  [(set (match_operand:SI 0 "register_operand" "=r")
3411	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3412		     (const_int 24)))]
3413  "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3414  "%V1ld.bu\\t %0,%1"
3415  [(set_attr "type" "load")])
3416
3417(define_insn ""
3418  [(set (match_operand:SI 0 "register_operand" "=r")
3419	(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3420		     (const_int 16)))]
3421  "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3422  "%V1ld.h\\t %0,%1"
3423  [(set_attr "type" "load")])
3424
3425(define_insn ""
3426  [(set (match_operand:SI 0 "register_operand" "=r")
3427	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3428		     (const_int 16)))]
3429  "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3430  "%V1ld.hu\\t %0,%1"
3431  [(set_attr "type" "load")])
3432
3433;;- arithmetic shift instructions.
3434
3435;; @@ Do the optimized patterns with -1 get used?  Perhaps operand 1 should
3436;; be arith32_operand?
3437
3438;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3439(define_insn "tbnd"
3440  [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3441		 (match_operand:SI 1 "arith_operand" "rI"))
3442	    (const_int 7))]
3443  ""
3444  "tbnd %0,%1"
3445  [(set_attr "type" "weird")
3446   (set_attr "length" "1")])
3447
3448;; Just in case the optimizer decides to fold away the test.
3449(define_insn ""
3450  [(trap_if (const_int 1) (const_int 7))]
3451  ""
3452  "tbnd %#r31,0"
3453  [(set_attr "type" "weird")
3454   (set_attr "length" "1")])
3455
3456(define_expand "ashlsi3"
3457  [(set (match_operand:SI 0 "register_operand" "")
3458	(ashift:SI (match_operand:SI 1 "register_operand" "")
3459		   (match_operand:SI 2 "arith32_operand" "")))]
3460  ""
3461  "
3462{
3463  if (GET_CODE (operands[2]) == CONST_INT)
3464    {
3465      if ((unsigned) INTVAL (operands[2]) > 31)
3466	{
3467	  if (TARGET_TRAP_LARGE_SHIFT)
3468	    emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3469				 GEN_INT (31)));
3470	  else
3471	    emit_move_insn (operands[0], const0_rtx);
3472	  DONE;
3473	}
3474    }
3475
3476  else if (TARGET_TRAP_LARGE_SHIFT)
3477    emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3478
3479  else if (TARGET_HANDLE_LARGE_SHIFT)
3480    {
3481      rtx reg = gen_reg_rtx (SImode);
3482      emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3483      emit_insn (gen_sleu (reg));
3484      emit_insn (gen_andsi3 (reg, operands[1], reg));
3485      operands[1] = reg;
3486    }
3487}")
3488
3489(define_insn ""
3490  [(set (match_operand:SI 0 "register_operand" "=r,r")
3491	(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3492		   (match_operand:SI 2 "arith5_operand" "r,K")))]
3493  ""
3494  "@
3495   mak %0,%1,%2
3496   mak %0,%1,0<%2>"
3497  [(set_attr "type" "bit")])
3498
3499(define_expand "ashrsi3"
3500  [(set (match_operand:SI 0 "register_operand" "")
3501	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3502		     (match_operand:SI 2 "arith32_operand" "")))]
3503  ""
3504  "
3505{
3506  if (GET_CODE (operands[2]) == CONST_INT)
3507    {
3508      if ((unsigned) INTVAL (operands[2]) > 31)
3509	{
3510	  if (TARGET_TRAP_LARGE_SHIFT)
3511	    {
3512	      emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3513				   GEN_INT (31)));
3514	      DONE;
3515	    }
3516	  else
3517	    operands[2] = GEN_INT (31);
3518	}
3519    }
3520
3521  else if (TARGET_TRAP_LARGE_SHIFT)
3522    emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3523
3524  else if (TARGET_HANDLE_LARGE_SHIFT)
3525    {
3526      rtx reg = gen_reg_rtx (SImode);
3527      emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3528      emit_insn (gen_sgtu (reg));
3529      emit_insn (gen_iorsi3 (reg, operands[2], reg));
3530      operands[2] = reg;
3531    }
3532}")
3533
3534(define_insn ""
3535  [(set (match_operand:SI 0 "register_operand" "=r,r")
3536	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3537		     (match_operand:SI 2 "arith5_operand" "r,K")))]
3538  ""
3539  "@
3540   ext %0,%1,%2
3541   ext %0,%1,0<%2>"
3542  [(set_attr "type" "bit")])
3543
3544;;- logical shift instructions.  Logical shift left becomes arithmetic
3545;; shift left.
3546
3547(define_expand "lshrsi3"
3548  [(set (match_operand:SI 0 "register_operand" "")
3549	(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3550		     (match_operand:SI 2 "arith32_operand" "")))]
3551  ""
3552  "
3553{
3554  if (GET_CODE (operands[2]) == CONST_INT)
3555    {
3556      if ((unsigned) INTVAL (operands[2]) > 31)
3557	{
3558	  if (TARGET_TRAP_LARGE_SHIFT)
3559	    emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3560				 GEN_INT (31)));
3561	  else
3562	    emit_move_insn (operands[0], const0_rtx);
3563	  DONE;
3564	}
3565    }
3566
3567  else if (TARGET_TRAP_LARGE_SHIFT)
3568    emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3569
3570  else if (TARGET_HANDLE_LARGE_SHIFT)
3571    {
3572      rtx reg = gen_reg_rtx (SImode);
3573      emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3574      emit_insn (gen_sleu (reg));
3575      emit_insn (gen_andsi3 (reg, operands[1], reg));
3576      operands[1] = reg;
3577    }
3578}")
3579
3580(define_insn ""
3581  [(set (match_operand:SI 0 "register_operand" "=r,r")
3582	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3583		     (match_operand:SI 2 "arith5_operand" "r,K")))]
3584  ""
3585  "@
3586   extu %0,%1,%2
3587   extu %0,%1,0<%2>"
3588  [(set_attr "type" "bit")])
3589
3590;;- rotate instructions
3591
3592(define_expand "rotlsi3"
3593  [(set (match_operand:SI 0 "register_operand" "")
3594	(rotatert:SI (match_operand:SI 1 "register_operand" "")
3595		     (match_operand:SI 2 "arith32_operand" "")))]
3596  ""
3597  "
3598{
3599  if (GET_CODE (operands[2]) == CONST_INT
3600      && (unsigned) INTVAL (operands[2]) >= 32)
3601    operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3602  else
3603    {
3604      rtx op = gen_reg_rtx (SImode);
3605      emit_insn (gen_negsi2 (op, operands[2]));
3606      operands[2] = op;
3607    }
3608}")
3609
3610(define_insn "rotrsi3"
3611  [(set (match_operand:SI 0 "register_operand" "=r")
3612	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
3613		     (match_operand:SI 2 "arith_operand" "rI")))]
3614  ""
3615  "rot %0,%1,%2"
3616  [(set_attr "type" "bit")])
3617
3618;; find first set.
3619
3620;; The ff1 instruction searches from the most significant bit while ffs
3621;; searches from the least significant bit.  The bit index and treatment of
3622;; zero also differ.  This amazing sequence was discovered using the GNU
3623;; Superoptimizer.
3624
3625(define_insn "ffssi2"
3626  [(set (match_operand:SI 0 "register_operand" "=r,&r")
3627	(ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3628   (clobber (reg:CC 0))
3629   (clobber (match_scratch:SI 2 "=r,X"))]
3630  ""
3631  "@
3632   subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3633   subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3634  [(set_attr "type" "marith")
3635   (set_attr "length" "4")])
3636
3637;; Bit field instructions.
3638
3639(define_insn ""
3640  [(set (match_operand:SI 0 "register_operand" "=r")
3641	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3642			 (const_int 32)
3643			 (const_int 0)))]
3644  ""
3645  "or %0,%#r0,%1")
3646
3647(define_insn "extv"
3648  [(set (match_operand:SI 0 "register_operand" "=r")
3649	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3650			 (match_operand:SI 2 "int5_operand" "")
3651			 (match_operand:SI 3 "int5_operand" "")))]
3652  ""
3653{
3654  operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3655  return "ext %0,%1,%2<%4>";  /* <(32-%2-%3)> */
3656}
3657  [(set_attr "type" "bit")])
3658
3659(define_insn ""
3660  [(set (match_operand:SI 0 "register_operand" "=r")
3661	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3662			 (const_int 32)
3663			 (const_int 0)))]
3664  ""
3665  "or %0,%#r0,%1")
3666
3667(define_insn "extzv"
3668  [(set (match_operand:SI 0 "register_operand" "=r")
3669	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3670			 (match_operand:SI 2 "int5_operand" "")
3671			 (match_operand:SI 3 "int5_operand" "")))]
3672  ""
3673{
3674  operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3675  return "extu %0,%1,%2<%4>";  /* <(32-%2-%3)> */
3676}
3677  [(set_attr "type" "bit")])
3678
3679(define_insn ""
3680  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3681			 (match_operand:SI 1 "int5_operand" "")
3682			 (match_operand:SI 2 "int5_operand" ""))
3683	(const_int 0))]
3684  ""
3685{
3686  operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3687  return "clr %0,%0,%1<%3>";  /* <(32-%1-%2)> */
3688}
3689  [(set_attr "type" "bit")])
3690
3691(define_insn ""
3692  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3693			 (match_operand:SI 1 "int5_operand" "")
3694			 (match_operand:SI 2 "int5_operand" ""))
3695	(const_int -1))]
3696  ""
3697{
3698  operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3699  return "set %0,%0,%1<%3>";  /* <(32-%1-%2)> */
3700}
3701  [(set_attr "type" "bit")])
3702
3703(define_insn ""
3704  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3705			 (match_operand:SI 1 "int5_operand" "")
3706			 (match_operand:SI 2 "int5_operand" ""))
3707	(match_operand:SI 3 "int32_operand" "n"))]
3708  ""
3709{
3710  int value = INTVAL (operands[3]);
3711
3712  if (INTVAL (operands[1]) < 32)
3713    value &= (1 << INTVAL (operands[1])) - 1;
3714
3715  operands[2] = GEN_INT (32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3716
3717  value <<= INTVAL (operands[2]);
3718  operands[3] = GEN_INT (value);
3719
3720  if (SMALL_INTVAL (value))
3721    return "clr %0,%0,%1<%2>\;or %0,%0,%3";
3722  else if ((value & 0x0000ffff) == 0)
3723    return "clr %0,%0,%1<%2>\;or.u %0,%0,%X3";
3724  else
3725    return "clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3";
3726}
3727  [(set_attr "type" "marith")
3728   (set_attr "length" "3")]) ; may be 2 or 3.
3729
3730;; negate insns
3731(define_insn "negsi2"
3732  [(set (match_operand:SI 0 "register_operand" "=r")
3733	(neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3734  ""
3735  "subu %0,%#r0,%1")
3736
3737(define_insn ""
3738  [(set (match_operand:SF 0 "register_operand" "=r,x")
3739	(float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3740  ""
3741  "@
3742   fsub.ssd %0,%#r0,%1
3743   fsub.ssd %0,%#x0,%1"
3744  [(set_attr "type" "dpadd")])
3745
3746(define_insn "negdf2"
3747  [(set (match_operand:DF 0 "register_operand" "=&r,r")
3748	(neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3749  ""
3750  "@
3751   xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3752   xor.u %0,%0,0x8000"
3753  [(set_attr "type" "marith,arith")])
3754
3755(define_insn "negsf2"
3756  [(set (match_operand:SF 0 "register_operand" "=r")
3757	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
3758  ""
3759  "xor.u %0,%1,0x8000")
3760
3761;; absolute value insns for floating-point (integer abs can be done using the
3762;; machine-independent sequence).
3763
3764(define_insn "absdf2"
3765  [(set (match_operand:DF 0 "register_operand" "=&r,r")
3766	(abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3767  ""
3768  "@
3769   and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3770   and.u %0,%0,0x7fff"
3771  [(set_attr "type" "marith,arith")])
3772
3773(define_insn "abssf2"
3774  [(set (match_operand:SF 0 "register_operand" "=r")
3775	(abs:SF (match_operand:SF 1 "register_operand" "r")))]
3776  ""
3777  "and.u %0,%1,0x7fff")
3778
3779;; Subroutines of "casesi".
3780
3781;; Operand 0 is index
3782;; operand 1 is the minimum bound
3783;; operand 2 is the maximum bound - minimum bound + 1
3784;; operand 3 is CODE_LABEL for the table;
3785;; operand 4 is the CODE_LABEL to go to if index out of range.
3786
3787(define_expand "casesi"
3788  ;; We don't use these for generating the RTL, but we must describe
3789  ;; the operands here.
3790  [(match_operand:SI 0 "general_operand" "")
3791   (match_operand:SI 1 "immediate_operand" "")
3792   (match_operand:SI 2 "immediate_operand" "")
3793   (match_operand 3 "" "")
3794   (match_operand 4 "" "")]
3795  ""
3796  "
3797{
3798  register rtx index_diff = gen_reg_rtx (SImode);
3799  register rtx low = GEN_INT (-INTVAL (operands[1]));
3800  register rtx label = gen_rtx_LABEL_REF (Pmode, operands[3]);
3801  register rtx base = NULL_RTX;
3802
3803  if (! CASE_VECTOR_INSNS)
3804    /* These instructions are likely to be scheduled and made loop invariant.
3805       This decreases the cost of the dispatch at the expense of the default
3806       case.  */
3807    base = force_reg (SImode, memory_address_noforce (SImode, label));
3808
3809  /* Compute the index difference and handle the default case.  */
3810  emit_insn (gen_addsi3 (index_diff,
3811			 force_reg (SImode, operands[0]),
3812			 ADD_INT (low) ? low : force_reg (SImode, low)));
3813  emit_insn (gen_cmpsi (index_diff, operands[2]));
3814  /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3815     entry to the table.  However, that doesn't seem to win on the m88110.  */
3816  emit_jump_insn (gen_bgtu (operands[4]));
3817
3818  if (CASE_VECTOR_INSNS)
3819    /* Call the jump that will branch to the appropriate case.  */
3820    emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3821  else
3822    /* Load the table entry and jump to it.  */
3823    emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3824
3825  /* Claim that flow drops into the table so it will be adjacent by not
3826     emitting a barrier.  */
3827  DONE;
3828}")
3829
3830(define_expand "casesi_jump"
3831  [(set (match_operand:SI 0 "" "")
3832	(mem:SI (plus:SI (match_operand:SI 1 "" "")
3833			 (mult:SI (match_operand:SI 2 "" "")
3834				  (const_int 4)))))
3835   (parallel [(set (pc) (match_dup 0))
3836              (use (label_ref (match_operand 3 "" "")))])]
3837  ""
3838  "")
3839
3840(define_insn ""
3841  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3842   (use (label_ref (match_operand 1 "" "")))]
3843  ""
3844  "jmp%. %0"
3845  [(set_attr "type" "jump")])
3846
3847;; The bsr.n instruction is directed to the END of the table.  See
3848;; ASM_OUTPUT_CASE_END.
3849
3850(define_insn "casesi_enter"
3851  [(set (pc) (match_operand 0 "" ""))
3852   (use (match_operand:SI 1 "register_operand" "r"))
3853   ;; The USE here is so that at least one jump-insn will refer to the label,
3854   ;; to keep it alive in jump_optimize.
3855   (use (label_ref (match_operand 2 "" "")))
3856   (clobber (reg:SI 1))]
3857  ""
3858{
3859  if (flag_delayed_branch)
3860    return "bsr.n %0e\;lda %#r1,%#r1[%1]";
3861  m88k_case_index = REGNO (operands[1]);
3862  return "bsr %0e";
3863}
3864  [(set_attr "type" "weird")
3865   (set_attr "length" "3")]) ; Including the "jmp r1".
3866
3867;;- jump to subroutine
3868(define_expand "call"
3869  [(parallel [(call (match_operand:SI 0 "" "")
3870		    (match_operand 1 "" ""))
3871	      (clobber (reg:SI 1))])]
3872  ""
3873  "
3874{
3875  gcc_assert (GET_CODE (operands[0]) == MEM);
3876
3877  if (! call_address_operand (XEXP (operands[0], 0), SImode)) /* Pmode ? */
3878    operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
3879			       force_reg (Pmode, XEXP (operands[0], 0)));
3880}")
3881
3882(define_insn ""
3883  [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3884		    (match_operand 1 "" ""))
3885	      (clobber (reg:SI 1))])]
3886  ""
3887  "* return output_call (operands, operands[0]);"
3888  [(set_attr "type" "call")])
3889
3890(define_expand "call_value"
3891  [(parallel [(set (match_operand 0 "register_operand" "")
3892		   (call (match_operand:SI 1 "" "")
3893			 (match_operand 2 "" "")))
3894	      (clobber (reg:SI 1))])]
3895  ""
3896  "
3897{
3898  gcc_assert (GET_CODE (operands[1]) == MEM);
3899
3900  if (! call_address_operand (XEXP (operands[1], 0), SImode))
3901    operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
3902			       force_reg (Pmode, XEXP (operands[1], 0)));
3903}")
3904
3905(define_insn ""
3906  [(parallel [(set (match_operand 0 "register_operand" "=r")
3907		   (call (mem:SI
3908			  (match_operand:SI 1 "call_address_operand" "rQ"))
3909			 (match_operand 2 "" "")))
3910	      (clobber (reg:SI 1))])]
3911  ""
3912  "* return output_call (operands, operands[1]);"
3913  [(set_attr "type" "call")])
3914
3915;; Nop instruction and others
3916
3917(define_insn "nop"
3918  [(const_int 0)]
3919  ""
3920  "ff0 %#r0,%#r0"
3921  [(set_attr "type" "bit")])
3922
3923(define_insn "return"
3924  [(return)]
3925  "null_prologue()"
3926  "jmp%. %#r1"
3927  [(set_attr "type" "jump")])
3928
3929(define_expand "prologue"
3930  [(use (const_int 0))]
3931  ""
3932{
3933  m88k_expand_prologue ();
3934  DONE;
3935})
3936
3937(define_expand "epilogue"
3938  [(use (const_int 0))]
3939  ""
3940{
3941  m88k_expand_epilogue ();
3942})
3943
3944(define_insn "blockage"
3945  [(unspec_volatile [(const_int 0)] 0)]
3946  ""
3947  ""
3948  [(set_attr "length" "0")])
3949
3950(define_insn "indirect_jump"
3951  [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3952  ""
3953  "jmp%. %0"
3954  [(set_attr "type" "jump")])
3955
3956(define_insn "jump"
3957  [(set (pc)
3958	(label_ref (match_operand 0 "" "")))]
3959  ""
3960  "br%. %l0"
3961  [(set_attr "type" "jump")])
3962
3963;; This insn is used for some loop tests, typically loops reversed when
3964;; strength reduction is used.  It is actually created when the instruction
3965;; combination phase combines the special loop test.  Since this insn
3966;; is both a jump insn and has an output, it must deal with its own
3967;; reloads, hence the `m' constraints.  The `!' constraints direct reload
3968;; to not choose the register alternatives in the event a reload is needed.
3969
3970(define_expand "decrement_and_branch_until_zero"
3971  [(parallel [(set (pc)
3972		   (if_then_else
3973		    (match_operator 0 "relop_no_unsigned"
3974				    [(match_operand:SI 1 "register_operand" "")
3975				     (const_int 0)])
3976		    (label_ref (match_operand 2 "" ""))
3977		    (pc)))
3978	      (set (match_dup 1)
3979		   (plus:SI (match_dup 1)
3980			    (match_operand:SI 3 "add_operand" "")))
3981	      (clobber (match_scratch:SI 4 ""))
3982	      (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])]
3983  ""
3984  "")
3985
3986(define_insn ""
3987  [(set (pc)
3988	(if_then_else
3989	 (match_operator 0 "relop_no_unsigned"
3990			 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
3991			  (const_int 0)])
3992	  (label_ref (match_operand 2 "" ""))
3993	  (pc)))
3994   (set (match_dup 1)
3995	(plus:SI (match_dup 1)
3996		 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
3997   (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
3998   (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
3999  "find_reg_note (insn, REG_NONNEG, 0)"
4000  "@
4001   bcnd.n %B0,%1,%2\;addu %1,%1,%3
4002   bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4003   ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4004   ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4005  [(set_attr "type" "weird")
4006   (set_attr "length" "2,2,4,4")])
4007
4008;; Special insn to serve as the last insn of a define_expand.  This insn
4009;; will generate no code.
4010
4011(define_expand "dummy"
4012  [(set (match_operand 0 "" "") (match_dup 0))]
4013  ""
4014  "")
4015