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 ;; Currently maintained by (gcc@dg-rtp.dg.com)
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Attribute describing the processor. This attribute must match exactly
28 ;; with the processor_type enumeration in m88k.h.
31 (define_attr "cpu" "m88100,m88110,m88000"
32 (const (symbol_ref "m88k_cpu")))
34 ; Type of each instruction. Default is arithmetic.
35 ; I'd like to write the list as this, but genattrtab won't accept it.
37 ; "branch,jump,call, ; flow-control instructions
38 ; load,store,loadd,loada, ; data unit instructions
39 ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
40 ; spmul,dpmul,imul, ; FPU multiply instructions
41 ; arith,bit,mov ; integer unit instructions
42 ; marith,weird" ; multi-word instructions
44 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
46 "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
47 (const_string "arith"))
49 (define_attr "fpu" "yes,no"
51 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
52 (const_string "yes") (const_string "no")))
54 ; Length in # of instructions of each insn. The values are not exact, but
56 (define_attr "length" ""
57 (cond [(eq_attr "type" "marith,weird,branch")
61 ; Describe a user's asm statement.
62 (define_asm_attributes
63 [(set_attr "type" "weird")])
65 ; Define the delay slot requirements for branches and calls.
66 ; The m88100 annuls instructions if a conditional branch is taken.
67 ; For insns of TYPE_BRANCH that are multi-word instructions, the
68 ; delay slot applies to the first instruction.
70 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
71 ; be a call or branch.
73 (define_delay (eq_attr "type" "branch,jump")
76 (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
77 (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
78 (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
79 (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
81 ; output_call supports an unconditional branch in the delay slot of
82 ; a call. (@@ Support for this case is expected in reorg.c soon.)
84 (define_delay (eq_attr "type" "call")
85 [(eq_attr "type" "!branch,call,marith,weird") ; required.
88 ; An abstract block diagram of the function units for the m88100.
95 ; ,----------'| | `----------------------.
97 ; load | store | | arith | | |
98 ; | | | +-v-v-+ | dp source
100 ; store | | | div +-v-v-+
101 ; ,------. | | | ,-----. ,-----------' `-----------.
103 ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+
104 ; | | stage 2 | | | `---| add 2 | | mul 2 |
105 ; | +---------+ | +--v--+ +-------+ imul +-------+
106 ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |
107 ; | +---------+ | +--v--+ +-------+ | +-------+
108 ; | | stage 0 | | | | add 4 | | | mul 4 |
109 ; | +--v---v--+ | | +---v---+ | +-------+
110 ; | | | | | | | | mul 5 |
111 ; | * | | | | | +---v---+
112 ; | | | | | +----v----+ |
113 ; | load | | | fp add `------>| fp last |<------' fp mul
114 ; | | | | +---v-v--^+
116 ; | | | | | `--' dp dest
117 ; | | +--v-----v--+ |
118 ; | `--->| writeback |<--------------------'
121 ; `------------------' *
123 ; The decode unit need not be specified.
124 ; Consideration of writeback contention is critical to superb scheduling.
126 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
127 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
129 ; Describing the '100 alu is currently not useful.
130 ;(define_function_unit "alu" 1 0 (eq_attr "type"
131 ; "!store,marith,weird") 1 0)
132 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
134 (define_function_unit "alu" 1 0
135 (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
136 (define_function_unit "alu" 1 0
137 (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
139 (define_function_unit "bit" 1 0
140 (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
142 (define_function_unit "mem100" 1 0
143 (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
144 (define_function_unit "mem100" 1 0
145 (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
146 (define_function_unit "mem100" 1 0
147 (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
149 (define_function_unit "mem110" 1 0
150 (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
151 (define_function_unit "mem110" 1 0
152 (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
154 ; The times are adjusted to include fp1 and fplast, but then are further
155 ; adjusted based on the actual generated code. The notation to the right
156 ; is the total latency. A range denotes a group of instructions and/or
157 ; conditions (the extra clock of fplast time with some sequences).
159 (define_function_unit "fpmul100" 1 0
160 (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8
161 (define_function_unit "fpmul100" 1 0
162 (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10
163 (define_function_unit "fpmul100" 1 0
164 (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4
166 (define_function_unit "fpmul110" 1 0
167 (and (eq_attr "type" "imul,spmul,dpmul")
168 (eq_attr "cpu" "!m88100")) 5 2) ; 3
170 (define_function_unit "fpadd100" 1 5
171 (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6
172 (define_function_unit "fpadd100" 1 5
173 (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7
175 (define_function_unit "fpadd110" 1 0
176 (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3
177 (define_function_unit "fpadd110" 1 0
178 (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1
180 (define_function_unit "fpadd100" 1 5
181 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31
182 (define_function_unit "fpadd100" 1 5
183 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61
184 (define_function_unit "fpadd100" 1 5
185 (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38
187 (define_function_unit "div" 1 1
188 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13
189 (define_function_unit "div" 1 1
190 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23
191 (define_function_unit "div" 1 1
192 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18
194 ;; Superoptimizer sequences
196 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
201 [(set (match_operand:SI 0 "register_operand" "=r")
202 (minus:SI (match_operand:SI 1 "register_operand" "r")
203 (geu:SI (match_operand:SI 2 "register_operand" "r")
204 (match_operand:SI 3 "register_operand" "r"))))]
206 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
208 (plus:SI (match_dup 1)
209 (unspec:SI [(const_int 0)
213 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
218 [(set (match_operand:SI 0 "register_operand" "=r")
219 (minus:SI (match_operand:SI 1 "register_operand" "r")
220 (leu:SI (match_operand:SI 3 "register_operand" "r")
221 (match_operand:SI 2 "register_operand" "r"))))]
223 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
225 (plus:SI (match_dup 1)
226 (unspec:SI [(const_int 0)
230 ;; eq0+: { r = (v0 == 0) + v1; }
235 [(set (match_operand:SI 0 "register_operand" "=r")
236 (minus:SI (match_operand:SI 1 "register_operand" "r")
237 (eq:SI (match_operand:SI 2 "register_operand" "r")
240 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
242 (plus:SI (match_dup 1)
243 (unspec:SI [(const_int 0)
247 ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
252 [(set (match_operand:SI 0 "register_operand" "=r")
253 (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
254 (match_operand:SI 3 "register_operand" "r"))
255 (match_operand:SI 1 "register_operand" "r")))]
257 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
259 (minus:SI (match_dup 1)
260 (unspec:SI [(const_int 0)
264 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
269 [(set (match_operand:SI 0 "register_operand" "=r")
270 (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
271 (match_operand:SI 2 "register_operand" "r"))
272 (match_operand:SI 1 "register_operand" "r")))]
274 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
276 (minus:SI (match_dup 1)
277 (unspec:SI [(const_int 0)
281 ;; ne0-: { r = v1 - (v0 != 0); }
286 [(set (match_operand:SI 0 "register_operand" "=r")
287 (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
289 (match_operand:SI 1 "register_operand" "r")))]
291 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
293 (minus:SI (match_dup 1)
294 (unspec:SI [(const_int 0)
298 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
303 [(set (match_operand:SI 0 "register_operand" "=r")
304 (minus:SI (match_operand:SI 1 "register_operand" "r")
306 (match_operand:SI 2 "register_operand" "r")
310 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
312 (minus:SI (match_dup 1)
313 (unspec:SI [(const_int 0)
317 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
318 ;; (tege@sics.se). They've changed since then, so don't complain to him
319 ;; if they don't work right.
321 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions
322 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
323 ;; special needs to be done here.
325 ;; Optimize possible cases of the set instruction.
328 [(set (match_operand:SI 0 "register_operand" "=r")
329 (ashift:SI (const_int -1)
330 (match_operand:SI 1 "register_operand" "r")))]
333 [(set_attr "type" "bit")])
336 [(set (match_operand:SI 0 "register_operand" "=r")
337 (ior:SI (ashift:SI (const_int -1)
338 (match_operand:SI 1 "register_operand" "r"))
339 (match_operand:SI 2 "register_operand" "r")))]
342 [(set_attr "type" "bit")])
345 [(set (match_operand:SI 0 "register_operand" "=r")
346 (ior:SI (match_operand:SI 1 "register_operand" "r")
347 (ashift:SI (const_int -1)
348 (match_operand:SI 2 "register_operand" "r"))))]
351 [(set_attr "type" "bit")])
353 ;; Optimize possible cases of the mak instruction.
356 [(set (match_operand:SI 0 "register_operand" "=r")
357 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
358 (match_operand:SI 2 "int5_operand" ""))
359 (match_operand:SI 3 "immediate_operand" "n")))]
360 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
363 operands[4] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3])
364 >> INTVAL(operands[2]))));
365 return \"mak %0,%1,%4<%2>\";
367 [(set_attr "type" "bit")])
369 ;; Optimize possible cases of output_and.
372 [(set (match_operand:SI 0 "register_operand" "=r")
373 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
374 (match_operand:SI 2 "int5_operand" "")
375 (match_operand:SI 3 "int5_operand" ""))
376 (match_operand:SI 4 "int5_operand" "")))]
377 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
381 = GEN_INT (((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
382 return output_and (operands);
384 [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.
386 ;; Improve logical operations on compare words
388 ;; We define all logical operations on CCmode values to preserve the pairwise
389 ;; relationship of the compare bits. This allows a future branch prediction
390 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
391 ;; THIS IS CURRENTLY FALSE!
393 ;; Opportunities arise when conditional expressions using && and || are made
394 ;; unconditional. When these are used to branch, the sequence is
395 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create
396 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
397 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
399 ;; When the extracted conditions are the same, the define_split patterns
400 ;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed
401 ;; conditions match, one compare word can be complemented, resulting in
402 ;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.
403 ;; If the conditions don't line up, one can be rotated. To keep the pairwise
404 ;; relationship, it may be necessary to both rotate and complement. Rotating
405 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
406 ;; we don't do this for ext/ext/{and,or}.
408 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
409 ;; into an alternate form of bb0 and bb1.
412 [(set (match_operand:SI 0 "register_operand" "=r")
414 (match_operator 1 "even_relop"
415 [(match_operand 2 "partial_ccmode_register_operand" "%r")
418 (match_operator 3 "relop"
419 [(match_operand 4 "partial_ccmode_register_operand" "r")
421 (clobber (match_operand:SI 5 "register_operand" "=r"))]
424 (ior:CCEVEN (match_dup 4)
427 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
428 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
429 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
430 ; /* The conditions match. */
431 else if (GET_CODE (operands[1])
432 == reverse_condition (GET_CODE (operands[3])))
433 /* Reverse the condition by complementing the compare word. */
434 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
437 /* Make the condition pairs line up by rotating the compare word. */
438 int cv1 = condition_value (operands[1]);
439 int cv2 = condition_value (operands[3]);
441 operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
442 GEN_INT (((cv2 & ~1) - (cv1 & ~1))
444 /* Reverse the condition if needed. */
445 if ((cv1 & 1) != (cv2 & 1))
446 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
450 [(set (match_operand:SI 0 "register_operand" "=r")
452 (match_operator 1 "odd_relop"
453 [(match_operand 2 "partial_ccmode_register_operand" "%r")
456 (match_operator 3 "odd_relop"
457 [(match_operand 4 "partial_ccmode_register_operand" "r")
459 (clobber (match_operand:SI 5 "register_operand" "=r"))]
462 (and:CCEVEN (match_dup 4)
465 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
466 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
467 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
468 ; /* The conditions match. */
471 /* Make the condition pairs line up by rotating the compare word. */
472 int cv1 = condition_value (operands[1]);
473 int cv2 = condition_value (operands[3]);
475 operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
476 GEN_INT ((cv2 - cv1) & 0x1f));
480 [(set (match_operand:SI 0 "register_operand" "=r")
482 (match_operator 1 "odd_relop"
483 [(match_operand 2 "partial_ccmode_register_operand" "%r")
486 (match_operator 3 "even_relop"
487 [(match_operand 4 "partial_ccmode_register_operand" "r")
489 (clobber (match_operand:SI 5 "register_operand" "=r"))]
492 (ior:CCEVEN (not:CC (match_dup 2))
495 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
496 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
497 if (GET_CODE (operands[1])
498 == reverse_condition (GET_CODE (operands[3])))
502 /* Make the condition pairs line up by rotating the compare word. */
503 int cv1 = condition_value (operands[1]);
504 int cv2 = condition_value (operands[3]);
506 operands[2] = gen_rtx_ROTATE (CCmode, operands[2],
507 GEN_INT (((cv1 & ~1) - (cv2 & ~1))
512 [(set (match_operand:SI 0 "register_operand" "=r")
513 (ior:SI (match_operator 1 "even_relop"
514 [(match_operand 2 "partial_ccmode_register_operand" "%r")
516 (match_operator 3 "relop"
517 [(match_operand 4 "partial_ccmode_register_operand" "r")
519 (clobber (match_operand:SI 5 "register_operand" "=r"))]
520 "GET_CODE (operands[1]) == GET_CODE (operands[3])
521 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
523 (ior:CCEVEN (match_dup 4)
526 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
527 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
528 /* Reverse the condition by complementing the compare word. */
529 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
530 operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
533 [(set (match_operand:SI 0 "register_operand" "=r")
534 (ior:SI (match_operator 1 "odd_relop"
535 [(match_operand 2 "partial_ccmode_register_operand" "%r")
537 (match_operator 3 "odd_relop"
538 [(match_operand 4 "partial_ccmode_register_operand" "r")
540 (clobber (match_operand:SI 5 "register_operand" "=r"))]
541 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
543 (and:CCEVEN (match_dup 4)
546 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
547 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
550 [(set (match_operand:SI 0 "register_operand" "=r")
551 (ior:SI (match_operator 1 "odd_relop"
552 [(match_operand 2 "partial_ccmode_register_operand" "%r")
554 (match_operator 3 "even_relop"
555 [(match_operand 4 "partial_ccmode_register_operand" "r")
557 (clobber (match_operand:SI 5 "register_operand" "=r"))]
558 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
560 (ior:CCEVEN (not:CC (match_dup 4))
563 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
564 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
567 [(set (match_operand:SI 0 "register_operand" "=r")
569 (match_operator 1 "even_relop"
570 [(match_operand 2 "partial_ccmode_register_operand" "%r")
573 (match_operator 3 "relop"
574 [(match_operand 4 "partial_ccmode_register_operand" "r")
576 (clobber (match_operand:SI 5 "register_operand" "=r"))]
579 (and:CCEVEN (match_dup 4)
582 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
583 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
584 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
585 ; /* The conditions match. */
586 else if (GET_CODE (operands[1])
587 == reverse_condition (GET_CODE (operands[3])))
588 /* Reverse the condition by complementing the compare word. */
589 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
592 /* Make the condition pairs line up by rotating the compare word. */
593 int cv1 = condition_value (operands[1]);
594 int cv2 = condition_value (operands[3]);
595 operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
596 GEN_INT (((cv2 & ~1) - (cv1 & ~1))
598 /* Reverse the condition if needed. */
599 if ((cv1 & 1) != (cv2 & 1))
600 operands[4] = gen_rtx_NOT (CCmode, operands[4]);
604 [(set (match_operand:SI 0 "register_operand" "=r")
606 (match_operator 1 "odd_relop"
607 [(match_operand 2 "partial_ccmode_register_operand" "%r")
610 (match_operator 3 "odd_relop"
611 [(match_operand 4 "partial_ccmode_register_operand" "r")
613 (clobber (match_operand:SI 5 "register_operand" "=r"))]
616 (ior:CCEVEN (match_dup 4)
619 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
620 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
621 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
622 ; /* The conditions match. */
625 /* Make the condition pairs line up by rotating the compare word. */
626 int cv1 = condition_value (operands[1]);
627 int cv2 = condition_value (operands[3]);
628 operands[4] = gen_rtx_ROTATE (CCmode, operands[4],
629 GEN_INT ((cv2 - cv1) & 0x1f));
633 [(set (match_operand:SI 0 "register_operand" "=r")
635 (match_operator 1 "odd_relop"
636 [(match_operand 2 "partial_ccmode_register_operand" "%r")
639 (match_operator 3 "even_relop"
640 [(match_operand 4 "partial_ccmode_register_operand" "r")
642 (clobber (match_operand:SI 5 "register_operand" "=r"))]
645 (and:CCEVEN (not:CC (match_dup 2))
648 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
649 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
650 if (GET_CODE (operands[1])
651 == reverse_condition (GET_CODE (operands[3])))
655 /* Make the condition pairs line up by rotating the compare word. */
656 int cv1 = condition_value (operands[1]);
657 int cv2 = condition_value (operands[3]);
658 operands[2] = gen_rtx_ROTATE (CCmode, operands[2],
659 GEN_INT (((cv1 & ~1) - (cv2 & ~1))
664 [(set (match_operand:SI 0 "register_operand" "=r")
665 (and:SI (match_operator 1 "even_relop"
666 [(match_operand 2 "partial_ccmode_register_operand" "%r")
668 (match_operator 3 "relop"
669 [(match_operand 4 "partial_ccmode_register_operand" "r")
671 (clobber (match_operand:SI 5 "register_operand" "=r"))]
672 "GET_CODE (operands[1]) == GET_CODE (operands[3])
673 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
675 (and:CCEVEN (match_dup 4)
678 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
679 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);
680 /* Reverse the condition by complementing the compare word. */
681 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
682 operands[4] = gen_rtx_NOT (CCmode, operands[4]);")
685 [(set (match_operand:SI 0 "register_operand" "=r")
686 (and:SI (match_operator 1 "odd_relop"
687 [(match_operand 2 "partial_ccmode_register_operand" "%r")
689 (match_operator 3 "odd_relop"
690 [(match_operand 4 "partial_ccmode_register_operand" "r")
692 (clobber (match_operand:SI 5 "register_operand" "=r"))]
693 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
695 (ior:CCEVEN (match_dup 4)
698 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
699 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
702 [(set (match_operand:SI 0 "register_operand" "=r")
703 (and:SI (match_operator 1 "odd_relop"
704 [(match_operand 2 "partial_ccmode_register_operand" "%r")
706 (match_operator 3 "even_relop"
707 [(match_operand 4 "partial_ccmode_register_operand" "r")
709 (clobber (match_operand:SI 5 "register_operand" "=r"))]
710 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
712 (and:CCEVEN (not:CC (match_dup 2))
715 (match_op_dup 3 [(match_dup 5) (const_int 0)]))]
716 "operands[5] = gen_rtx_SUBREG (CCEVENmode, operands[5], 0);")
719 ;; Logical operations on compare words.
722 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
723 (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
724 (match_operand 2 "partial_ccmode_register_operand" "r")))]
729 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
730 (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
731 (match_operand 2 "partial_ccmode_register_operand" "r")))]
736 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
737 (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
738 (match_operand 2 "partial_ccmode_register_operand" "r")))]
743 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
744 (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
745 (match_operand 2 "partial_ccmode_register_operand" "r")))]
750 [(set (match_operand:CC 0 "register_operand" "=r")
751 (rotate:CC (match_operand:CC 1 "register_operand" "r")
752 (match_operand:CC 2 "int5_operand" "")))]
755 [(set_attr "type" "bit")])
758 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
759 (rotate:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "r")
760 (match_operand:CC 2 "int5_operand" "")))]
763 [(set_attr "type" "bit")])
765 ;; rotate/and[.c] and rotate/ior[.c]
768 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
769 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
770 (match_operand:CC 2 "int5_operand" ""))
771 (match_operand 3 "partial_ccmode_register_operand" "r")))
772 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
775 (rotate:CC (match_dup 1) (match_dup 2)))
777 (ior:CCEVEN (match_dup 4) (match_dup 3)))]
781 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
782 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
783 (match_operand:CC 2 "int5_operand" ""))
784 (match_operand 3 "partial_ccmode_register_operand" "r")))
785 (clobber (match_scratch:CCEVEN 4 "=r"))]
790 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
791 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
792 (match_operand:CC 2 "int5_operand" "")))
793 (match_operand 3 "partial_ccmode_register_operand" "r")))
794 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
797 (rotate:CC (match_dup 1) (match_dup 2)))
799 (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
803 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
804 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
805 (match_operand:CC 2 "int5_operand" "")))
806 (match_operand 3 "partial_ccmode_register_operand" "r")))
807 (clobber (match_scratch:CCEVEN 4 "=r"))]
812 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
813 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
814 (match_operand:CC 2 "int5_operand" ""))
815 (match_operand 3 "partial_ccmode_register_operand" "r")))
816 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
819 (rotate:CC (match_dup 1) (match_dup 2)))
821 (and:CCEVEN (match_dup 4) (match_dup 3)))]
825 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
826 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
827 (match_operand:CC 2 "int5_operand" ""))
828 (match_operand 3 "partial_ccmode_register_operand" "r")))
829 (clobber (match_scratch:CCEVEN 4 "=r"))]
834 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
835 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
836 (match_operand:CC 2 "int5_operand" "")))
837 (match_operand 3 "partial_ccmode_register_operand" "r")))
838 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
841 (rotate:CC (match_dup 1) (match_dup 2)))
843 (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
847 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
848 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
849 (match_operand:CC 2 "int5_operand" "")))
850 (match_operand 3 "partial_ccmode_register_operand" "r")))
851 (clobber (match_scratch:CCEVEN 4 "=r"))]
856 ;; Recognize bcnd instructions for integer values. This is distinguished
857 ;; from a conditional branch instruction (below) with SImode instead of
863 (match_operator 0 "relop_no_unsigned"
864 [(match_operand:SI 1 "register_operand" "r")
866 (match_operand 2 "pc_or_label_ref" "")
867 (match_operand 3 "pc_or_label_ref" "")))]
869 "bcnd%. %R3%B0,%1,%P2%P3"
870 [(set_attr "type" "branch")])
872 ;; Recognize tests for sign and zero.
877 (match_operator 0 "equality_op"
878 [(match_operand:SI 1 "register_operand" "r")
879 (const_int -2147483648)])
880 (match_operand 2 "pc_or_label_ref" "")
881 (match_operand 3 "pc_or_label_ref" "")))]
883 "bcnd%. %R3%E0,%1,%P2%P3"
884 [(set_attr "type" "branch")])
889 (match_operator 0 "equality_op"
891 (match_operand:SI 1 "register_operand" "r")
895 (match_operand 2 "pc_or_label_ref" "")
896 (match_operand 3 "pc_or_label_ref" "")))]
898 "bcnd%. %R3%D0,%1,%P2%P3"
899 [(set_attr "type" "branch")])
901 ;; Recognize bcnd instructions for double integer values
906 (match_operator 0 "relop_no_unsigned"
908 (match_operand:SI 1 "register_operand" "r"))
910 (match_operand 2 "pc_or_label_ref" "")
911 (match_operand 3 "pc_or_label_ref" "")))]
913 "bcnd%. %R3%B0,%1,%P2%P3"
914 [(set_attr "type" "branch")])
919 (match_operator 0 "equality_op"
921 (match_operand:SI 1 "register_operand" "r"))
923 (match_operand 2 "pc_or_label_ref" "")
924 (match_operand 3 "pc_or_label_ref" "")))]
926 "bcnd%. %R3%B0,%1,%P2%P3"
927 [(set_attr "type" "branch")])
929 ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs
935 ; (match_operator 0 "relop_no_unsigned"
936 ; [(match_operand:DI 1 "register_operand" "r")
938 ; (match_operand 2 "pc_or_label_ref" "")
939 ; (match_operand 3 "pc_or_label_ref" "")))]
943 ; switch (GET_CODE (operands[0]))
947 ; /* I'm not sure if it's safe to use .n here. */
948 ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
951 ; return \"bcnd%. %R3%B0,%1,%P2%P3\";
954 ; rtx op2 = operands[2];
955 ; operands[2] = operands[3];
959 ; if (GET_CODE (operands[3]) == LABEL_REF)
962 ; operands[2] = gen_label_rtx ();
963 ; label_num = XINT (operands[2], 3);
965 ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
966 ; output_label (label_num);
970 ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
974 ;; Recognize bcnd instructions for single precision float values
975 ;; Exclude relational operations as they must signal NaNs.
977 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
982 (match_operator 0 "equality_op"
984 (match_operand:SF 1 "register_operand" "r"))
986 (match_operand 2 "pc_or_label_ref" "")
987 (match_operand 3 "pc_or_label_ref" "")))]
989 "bcnd%. %R3%D0,%1,%P2%P3"
990 [(set_attr "type" "branch")])
995 (match_operator 0 "equality_op"
996 [(match_operand:SF 1 "register_operand" "r")
998 (match_operand 2 "pc_or_label_ref" "")
999 (match_operand 3 "pc_or_label_ref" "")))]
1001 "bcnd%. %R3%D0,%1,%P2%P3"
1002 [(set_attr "type" "branch")])
1004 ;; Recognize bcnd instructions for double precision float values
1005 ;; Exclude relational operations as they must signal NaNs.
1010 (match_operator 0 "equality_op"
1011 [(match_operand:DF 1 "register_operand" "r")
1013 (match_operand 2 "pc_or_label_ref" "")
1014 (match_operand 3 "pc_or_label_ref" "")))]
1020 if (GET_CODE (operands[0]) == NE)
1022 rtx op2 = operands[2];
1023 operands[2] = operands[3];
1026 if (GET_CODE (operands[3]) == LABEL_REF)
1027 return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
1029 operands[3] = gen_label_rtx ();
1030 label_num = XINT (operands[3], 3);
1031 output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
1032 output_label (label_num);
1035 [(set_attr "type" "weird")
1036 (set_attr "length" "3")])
1038 ;; Recognize bb0 and bb1 instructions. These use two unusual template
1039 ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF
1040 ;; otherwise it outputs a 0. It then may print ".n" if the delay slot
1041 ;; is used. %Px does noting if `x' is PC and outputs the operand if `x'
1047 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1049 (match_operand:SI 1 "int5_operand" ""))
1051 (match_operand 2 "pc_or_label_ref" "")
1052 (match_operand 3 "pc_or_label_ref" "")))]
1054 "bb%L2 (31-%1),%0,%P2%P3"
1055 [(set_attr "type" "branch")])
1060 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1062 (match_operand:SI 1 "int5_operand" ""))
1064 (match_operand 2 "pc_or_label_ref" "")
1065 (match_operand 3 "pc_or_label_ref" "")))]
1067 "bb%L3 (31-%1),%0,%P2%P3"
1068 [(set_attr "type" "branch")])
1073 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1075 (match_operand:SI 1 "int5_operand" ""))
1077 (match_operand 2 "pc_or_label_ref" "")
1078 (match_operand 3 "pc_or_label_ref" "")))]
1080 "bb%L2 (31-%1),%0,%P2%P3"
1081 [(set_attr "type" "branch")])
1086 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1088 (match_operand:SI 1 "int5_operand" ""))
1090 (match_operand 2 "pc_or_label_ref" "")
1091 (match_operand 3 "pc_or_label_ref" "")))]
1093 "bb%L3 (31-%1),%0,%P2%P3"
1094 [(set_attr "type" "branch")])
1099 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1100 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1102 (match_operand 2 "pc_or_label_ref" "")
1103 (match_operand 3 "pc_or_label_ref" "")))]
1104 "(GET_CODE (operands[0]) == CONST_INT)
1105 != (GET_CODE (operands[1]) == CONST_INT)"
1106 "bb%L3 %p1,%0,%P2%P3"
1107 [(set_attr "type" "branch")])
1112 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1113 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1115 (match_operand 2 "pc_or_label_ref" "")
1116 (match_operand 3 "pc_or_label_ref" "")))]
1117 "(GET_CODE (operands[0]) == CONST_INT)
1118 != (GET_CODE (operands[1]) == CONST_INT)"
1119 "bb%L2 %p1,%0,%P2%P3"
1120 [(set_attr "type" "branch")])
1122 ;; The comparison operations store the comparison into a register and
1123 ;; record that register. The following Bxx or Sxx insn uses that
1124 ;; register as an input. To facilitate use of bcnd instead of cmp/bb1,
1125 ;; cmpsi records its operands and produces no code when any operand
1126 ;; is constant. In this case, the Bxx insns use gen_bcnd and the
1127 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
1129 ;; This could also be done for SFmode and DFmode having only beq and bne
1130 ;; use gen_bcnd. The others must signal NaNs. It seems though that zero
1131 ;; has already been copied into a register.
1133 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1134 ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can
1135 ;; use bcnd only if an operand is zero.
1137 ;; It is necessary to distinguish a register holding condition codes.
1138 ;; This is done by context.
1140 (define_expand "test"
1142 (compare:CC (match_operand 0 "" "")
1143 (match_operand 1 "" "")))]
1147 if (m88k_compare_reg)
1150 if (GET_CODE (operands[0]) == CONST_INT
1151 && ! SMALL_INT (operands[0]))
1152 operands[0] = force_reg (SImode, operands[0]);
1154 if (GET_CODE (operands[1]) == CONST_INT
1155 && ! SMALL_INT (operands[1]))
1156 operands[1] = force_reg (SImode, operands[1]);
1158 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1161 ; @@ The docs say don't do this. It's probably a nop since the insn looks
1162 ; identical to cmpsi against zero. Is there an advantage to providing
1163 ; this, perhaps with a different form?
1165 ;(define_expand "tstsi"
1166 ; [(set (match_dup 1)
1167 ; (compare:CC (match_operand:SI 0 "register_operand" "")
1172 ; m88k_compare_reg = 0;
1173 ; m88k_compare_op0 = operands[0];
1174 ; m88k_compare_op1 = const0_rtx;
1178 (define_expand "cmpsi"
1180 (compare:CC (match_operand:SI 0 "register_operand" "")
1181 (match_operand:SI 1 "arith32_operand" "")))]
1185 if (GET_CODE (operands[0]) == CONST_INT
1186 || GET_CODE (operands[1]) == CONST_INT)
1188 m88k_compare_reg = 0;
1189 m88k_compare_op0 = operands[0];
1190 m88k_compare_op1 = operands[1];
1193 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1196 (define_expand "cmpsf"
1198 (compare:CC (match_operand:SF 0 "register_operand" "")
1199 (match_operand:SF 1 "register_operand" "")))]
1201 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1203 (define_expand "cmpdf"
1205 (compare:CC (match_operand:DF 0 "general_operand" "")
1206 (match_operand:DF 1 "general_operand" "")))]
1210 operands[0] = legitimize_operand (operands[0], DFmode);
1211 operands[1] = legitimize_operand (operands[1], DFmode);
1212 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1215 ; @@ Get back to this later on.
1217 ;(define_insn "cmpdi"
1219 ; (compare:CC (match_operand:DI 0 "register_operand" "r")
1220 ; (match_operand:DI 1 "register_operand" "r")))]
1224 ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1225 ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */
1227 ; cc_status.mdep &= ~ MDEP_LS_MASK;
1229 ; operands[2] = gen_label_rtx ();
1230 ; /* Remember, %! is the condition code register and %@ is the
1231 ; literal synthesis register. */
1233 ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1236 ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1237 ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1238 ; output_label (XINT (operands[2], 3));
1242 ;; The actual compare instructions.
1245 [(set (match_operand:CC 0 "register_operand" "=r")
1246 (compare:CC (match_operand:SI 1 "register_operand" "rO")
1247 (match_operand:SI 2 "arith_operand" "rI")))]
1252 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1253 (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1254 (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1260 fcmp.sss %0,%1,%#x0"
1261 [(set_attr "type" "spcmp")])
1264 [(set (match_operand:CC 0 "register_operand" "=r,r")
1265 (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1267 (match_operand:SF 2 "register_operand" "r,x"))))]
1270 [(set_attr "type" "dpcmp")])
1273 [(set (match_operand:CC 0 "register_operand" "=r,r")
1274 (compare:CC (float_extend:DF
1275 (match_operand:SF 1 "register_operand" "r,x"))
1276 (match_operand:DF 2 "register_operand" "r,x")))]
1279 [(set_attr "type" "dpcmp")])
1282 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1283 (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1284 (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1290 fcmp.sds %0,%1,%#x0"
1291 [(set_attr "type" "dpcmp")])
1293 ;; Store condition code insns. The compare insns set a register
1294 ;; rather than cc0 and record that register for use here. See above
1295 ;; for the special treatment of cmpsi with a constant operand.
1297 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1299 (define_expand "seq"
1300 [(set (match_operand:SI 0 "register_operand" "")
1303 "operands[1] = emit_test (EQ, SImode);")
1305 (define_expand "sne"
1306 [(set (match_operand:SI 0 "register_operand" "")
1309 "operands[1] = emit_test (NE, SImode);")
1311 (define_expand "sgt"
1312 [(set (match_operand:SI 0 "register_operand" "")
1315 "operands[1] = emit_test (GT, SImode);")
1317 (define_expand "sgtu"
1318 [(set (match_operand:SI 0 "register_operand" "")
1321 "operands[1] = emit_test (GTU, SImode);")
1323 (define_expand "slt"
1324 [(set (match_operand:SI 0 "register_operand" "")
1327 "operands[1] = emit_test (LT, SImode);")
1329 (define_expand "sltu"
1330 [(set (match_operand:SI 0 "register_operand" "")
1333 "operands[1] = emit_test (LTU, SImode);")
1335 (define_expand "sge"
1336 [(set (match_operand:SI 0 "register_operand" "")
1339 "operands[1] = emit_test (GE, SImode);")
1341 (define_expand "sgeu"
1342 [(set (match_operand:SI 0 "register_operand" "")
1345 "operands[1] = emit_test (GEU, SImode);")
1347 (define_expand "sle"
1348 [(set (match_operand:SI 0 "register_operand" "")
1351 "operands[1] = emit_test (LE, SImode);")
1353 (define_expand "sleu"
1354 [(set (match_operand:SI 0 "register_operand" "")
1357 "operands[1] = emit_test (LEU, SImode);")
1359 ;; The actual set condition code instruction.
1362 [(set (match_operand:SI 0 "register_operand" "=r")
1363 (match_operator:SI 1 "relop"
1364 [(match_operand:CC 2 "register_operand" "r")
1368 [(set_attr "type" "bit")])
1371 [(set (match_operand:SI 0 "register_operand" "=r")
1372 (match_operator:SI 1 "even_relop"
1373 [(match_operand:CCEVEN 2 "register_operand" "r")
1377 [(set_attr "type" "bit")])
1380 [(set (match_operand:SI 0 "register_operand" "=r")
1381 (not:SI (match_operator:SI 1 "odd_relop"
1382 [(match_operand:CCEVEN 2 "register_operand" "r")
1385 "ext %0,%2,1<%!%C1>"
1386 [(set_attr "type" "bit")])
1389 [(set (match_operand:SI 0 "register_operand" "=r")
1390 (match_operator:SI 1 "odd_relop"
1391 [(match_operand:CCEVEN 2 "register_operand" "r")
1393 (clobber (match_operand:SI 3 "register_operand" "=r"))]
1395 [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1396 (set (match_dup 0) (not:SI (match_dup 3)))]
1400 [(set (match_operand:SI 0 "register_operand" "=r")
1401 (match_operator:SI 1 "odd_relop"
1402 [(match_operand:CCEVEN 2 "register_operand" "r")
1404 (clobber (match_scratch:SI 3 "=r"))]
1409 [(set (match_operand:SI 0 "register_operand" "=r")
1411 (match_operator:SI 1 "relop"
1412 [(match_operand:CC 2 "register_operand" "r")
1416 [(set_attr "type" "bit")])
1419 [(set (match_operand:SI 0 "register_operand" "=r")
1421 (match_operator:SI 1 "even_relop"
1422 [(match_operand:CCEVEN 2 "register_operand" "r")
1426 [(set_attr "type" "bit")])
1429 [(set (match_operand:SI 0 "register_operand" "=r")
1431 (not:SI (match_operator:SI 1 "odd_relop"
1432 [(match_operand:CCEVEN 2 "register_operand" "r")
1435 "extu %0,%2,1<%!%C1>"
1436 [(set_attr "type" "bit")])
1439 [(set (match_operand:SI 0 "register_operand" "=r")
1440 (neg:SI (match_operator:SI 1 "odd_relop"
1441 [(match_operand:CCEVEN 2 "register_operand" "r")
1443 (clobber (match_operand:SI 3 "register_operand" "=r"))]
1445 [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1447 (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1452 [(set (match_operand:SI 0 "register_operand" "=r")
1453 (neg:SI (match_operator:SI 1 "odd_relop"
1454 [(match_operand:CCEVEN 2 "register_operand" "r")
1456 (clobber (match_scratch:SI 3 "=r"))]
1463 ;; Conditional branch insns. The compare insns set a register
1464 ;; rather than cc0 and record that register for use here. See above
1465 ;; for the special case of cmpsi with a constant operand.
1467 (define_expand "bcnd"
1469 (if_then_else (match_operand 0 "" "")
1470 (label_ref (match_operand 1 "" ""))
1473 "if (m88k_compare_reg) abort ();")
1475 (define_expand "bxx"
1477 (if_then_else (match_operand 0 "" "")
1478 (label_ref (match_operand 1 "" ""))
1481 "if (m88k_compare_reg == 0) abort ();")
1483 (define_expand "beq"
1485 (if_then_else (eq (match_dup 1) (const_int 0))
1486 (label_ref (match_operand 0 "" ""))
1489 "if (m88k_compare_reg == 0)
1491 emit_bcnd (EQ, operands[0]);
1494 operands[1] = m88k_compare_reg;")
1496 (define_expand "bne"
1498 (if_then_else (ne (match_dup 1) (const_int 0))
1499 (label_ref (match_operand 0 "" ""))
1502 "if (m88k_compare_reg == 0)
1504 emit_bcnd (NE, operands[0]);
1507 operands[1] = m88k_compare_reg;")
1509 (define_expand "bgt"
1511 (if_then_else (gt (match_dup 1) (const_int 0))
1512 (label_ref (match_operand 0 "" ""))
1515 "if (m88k_compare_reg == 0)
1517 emit_bcnd (GT, operands[0]);
1520 operands[1] = m88k_compare_reg;")
1522 (define_expand "bgtu"
1524 (if_then_else (gtu (match_dup 1) (const_int 0))
1525 (label_ref (match_operand 0 "" ""))
1528 "if (m88k_compare_reg == 0)
1530 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1533 operands[1] = m88k_compare_reg;")
1535 (define_expand "blt"
1537 (if_then_else (lt (match_dup 1) (const_int 0))
1538 (label_ref (match_operand 0 "" ""))
1541 "if (m88k_compare_reg == 0)
1543 emit_bcnd (LT, operands[0]);
1546 operands[1] = m88k_compare_reg;")
1548 (define_expand "bltu"
1550 (if_then_else (ltu (match_dup 1) (const_int 0))
1551 (label_ref (match_operand 0 "" ""))
1554 "if (m88k_compare_reg == 0)
1556 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1559 operands[1] = m88k_compare_reg;")
1561 (define_expand "bge"
1563 (if_then_else (ge (match_dup 1) (const_int 0))
1564 (label_ref (match_operand 0 "" ""))
1567 "if (m88k_compare_reg == 0)
1569 emit_bcnd (GE, operands[0]);
1572 operands[1] = m88k_compare_reg;")
1574 (define_expand "bgeu"
1576 (if_then_else (geu (match_dup 1) (const_int 0))
1577 (label_ref (match_operand 0 "" ""))
1580 "if (m88k_compare_reg == 0)
1582 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1585 operands[1] = m88k_compare_reg;")
1587 (define_expand "ble"
1589 (if_then_else (le (match_dup 1) (const_int 0))
1590 (label_ref (match_operand 0 "" ""))
1593 "if (m88k_compare_reg == 0)
1595 emit_bcnd (LE, operands[0]);
1598 operands[1] = m88k_compare_reg;")
1600 (define_expand "bleu"
1602 (if_then_else (leu (match_dup 1) (const_int 0))
1603 (label_ref (match_operand 0 "" ""))
1606 "if (m88k_compare_reg == 0)
1608 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1611 operands[1] = m88k_compare_reg;")
1613 ;; The actual conditional branch instruction (both directions). This
1614 ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code
1615 ;; for the immediately following condition and reverses the condition iff
1616 ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs
1617 ;; the operand if `x' is a LABEL_REF.
1620 [(set (pc) (if_then_else
1621 (match_operator 0 "relop"
1622 [(match_operand:CC 1 "register_operand" "r")
1624 (match_operand 2 "pc_or_label_ref" "")
1625 (match_operand 3 "pc_or_label_ref" "")))]
1629 if (mostly_false_jump (insn, operands[0]))
1630 return \"bb0%. %R2%C0,%1,%P2%P3\";
1632 return \"bb1%. %R3%C0,%1,%P2%P3\";
1634 [(set_attr "type" "branch")])
1637 ;; Here branch prediction is sacrificed. To get it back, you need
1638 ;; - CCODD (CC mode where the ODD bits are valid)
1639 ;; - several define_split that can apply De Morgan's Law.
1640 ;; - transformations between CCEVEN and CCODD modes.
1644 [(set (pc) (if_then_else
1645 (match_operator 0 "even_relop"
1646 [(match_operand:CCEVEN 1 "register_operand" "r")
1648 (match_operand 2 "pc_or_label_ref" "")
1649 (match_operand 3 "pc_or_label_ref" "")))]
1651 "bb%L2%. %C0,%1,%P2%P3"
1652 [(set_attr "type" "branch")])
1655 [(set (pc) (if_then_else
1656 (match_operator 0 "odd_relop"
1657 [(match_operand:CCEVEN 1 "register_operand" "r")
1659 (match_operand 2 "pc_or_label_ref" "")
1660 (match_operand 3 "pc_or_label_ref" "")))]
1662 "bb%L3%. %!%C0,%1,%P2%P3"
1663 [(set_attr "type" "branch")])
1665 ;; Branch conditional on scc values. These arise from manipulations on
1666 ;; compare words above.
1667 ;; Are these really used ?
1672 (ne (match_operator 0 "relop"
1673 [(match_operand:CC 1 "register_operand" "r")
1676 (match_operand 2 "pc_or_label_ref" "")
1677 (match_operand 3 "pc_or_label_ref" "")))]
1679 "bb%L2 %C0,%1,%P2%P3"
1680 [(set_attr "type" "branch")])
1685 (ne (match_operator 0 "even_relop"
1686 [(match_operand:CCEVEN 1 "register_operand" "r")
1689 (match_operand 2 "pc_or_label_ref" "")
1690 (match_operand 3 "pc_or_label_ref" "")))]
1692 "bb%L2 %C0,%1,%P2%P3"
1693 [(set_attr "type" "branch")])
1698 (ne (match_operator 0 "odd_relop"
1699 [(match_operand:CCEVEN 1 "register_operand" "r")
1702 (match_operand 2 "pc_or_label_ref" "")
1703 (match_operand 3 "pc_or_label_ref" "")))]
1705 "bb%L3 %!%C0,%1,%P2%P3"
1706 [(set_attr "type" "branch")])
1711 (eq (match_operator 0 "relop"
1712 [(match_operand:CC 1 "register_operand" "r")
1715 (match_operand 2 "pc_or_label_ref" "")
1716 (match_operand 3 "pc_or_label_ref" "")))]
1718 "bb%L3 %C0,%1,%P2%P3"
1719 [(set_attr "type" "branch")])
1724 (eq (match_operator 0 "even_relop"
1725 [(match_operand:CCEVEN 1 "register_operand" "r")
1728 (match_operand 2 "pc_or_label_ref" "")
1729 (match_operand 3 "pc_or_label_ref" "")))]
1731 "bb%L3 %C0,%1,%P2%P3"
1732 [(set_attr "type" "branch")])
1737 (eq (match_operator 0 "odd_relop"
1738 [(match_operand:CCEVEN 1 "register_operand" "r")
1741 (match_operand 2 "pc_or_label_ref" "")
1742 (match_operand 3 "pc_or_label_ref" "")))]
1744 "bb%L2 %!%C0,%1,%P2%P3"
1745 [(set_attr "type" "branch")])
1747 (define_insn "locate1"
1748 [(set (match_operand:SI 0 "register_operand" "=r")
1749 (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1751 "or.u %0,%#r0,%#hi16(%1#abdiff)")
1753 (define_insn "locate2"
1754 [(parallel [(set (reg:SI 1) (pc))
1755 (set (match_operand:SI 0 "register_operand" "=r")
1756 (lo_sum:SI (match_dup 0)
1758 [(label_ref (match_operand 1 "" ""))] 0)))])]
1760 "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1761 [(set_attr "length" "2")])
1763 ;; SImode move instructions
1765 (define_expand "movsi"
1766 [(set (match_operand:SI 0 "general_operand" "")
1767 (match_operand:SI 1 "general_operand" ""))]
1771 if (emit_move_sequence (operands, SImode, 0))
1775 (define_expand "reload_insi"
1776 [(set (match_operand:SI 0 "register_operand" "=r")
1777 (match_operand:SI 1 "general_operand" ""))
1778 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1782 if (emit_move_sequence (operands, SImode, operands[2]))
1785 /* We don't want the clobber emitted, so handle this ourselves. */
1786 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
1791 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1792 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1793 "(register_operand (operands[0], SImode)
1794 || register_operand (operands[1], SImode)
1795 || operands[1] == const0_rtx)"
1807 [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1810 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1811 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1818 or.u %0,%#r0,%X1\;or %0,%0,%x1"
1819 [(set_attr "type" "arith,arith,arith,bit,marith")])
1821 ;; @@ Why the constraint "in"? Doesn't `i' include `n'?
1823 [(set (match_operand:SI 0 "register_operand" "=r")
1824 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1825 (match_operand:SI 2 "immediate_operand" "in")))]
1827 "or %0,%1,%#lo16(%g2)")
1829 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1830 ;; confuse them with real addresses.
1832 [(set (match_operand:SI 0 "register_operand" "=r")
1833 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1834 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1836 "or %0,%1,%#lo16(%g2)"
1837 ;; Need to set length for this arith insn because operand2
1838 ;; is not an "arith_operand".
1839 [(set_attr "length" "1")])
1842 [(set (match_operand:SI 0 "register_operand" "=r")
1843 (high:SI (match_operand 1 "" "")))]
1845 "or.u %0,%#r0,%#hi16(%g1)")
1847 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1848 ;; confuse them with real addresses.
1850 [(set (match_operand:SI 0 "register_operand" "=r")
1851 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1853 "or.u %0,%#r0,%#hi16(%g1)"
1854 ;; Need to set length for this arith insn because operand2
1855 ;; is not an arith_operand.
1856 [(set_attr "length" "1")])
1858 ;; HImode move instructions
1860 (define_expand "movhi"
1861 [(set (match_operand:HI 0 "general_operand" "")
1862 (match_operand:HI 1 "general_operand" ""))]
1866 if (emit_move_sequence (operands, HImode, 0))
1871 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1872 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1873 "(register_operand (operands[0], HImode)
1874 || register_operand (operands[1], HImode)
1875 || operands[1] == const0_rtx)"
1881 [(set_attr "type" "arith,load,store,arith")])
1884 [(set (match_operand:HI 0 "register_operand" "=r")
1885 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1886 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1888 "or %0,%1,%#lo16(%2)")
1890 ;; QImode move instructions
1892 (define_expand "movqi"
1893 [(set (match_operand:QI 0 "general_operand" "")
1894 (match_operand:QI 1 "general_operand" ""))]
1898 if (emit_move_sequence (operands, QImode, 0))
1903 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1904 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1905 "(register_operand (operands[0], QImode)
1906 || register_operand (operands[1], QImode)
1907 || operands[1] == const0_rtx)"
1913 [(set_attr "type" "arith,load,store,arith")])
1916 [(set (match_operand:QI 0 "register_operand" "=r")
1917 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1918 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1920 "or %0,%1,%#lo16(%2)")
1922 ;; DImode move instructions
1924 (define_expand "movdi"
1925 [(set (match_operand:DI 0 "general_operand" "")
1926 (match_operand:DI 1 "general_operand" ""))]
1930 if (emit_move_sequence (operands, DImode, 0))
1935 [(set (match_operand:DI 0 "register_operand" "=r,x")
1939 or %0,%#r0,0\;or %d0,%#r0,0
1941 [(set_attr "type" "marith,mov")])
1944 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1945 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1948 or %0,%#r0,%1\;or %d0,%#r0,%d1
1956 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1959 [(set (match_operand:DI 0 "register_operand" "=r")
1960 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1961 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1963 "or %0,%1,%#lo16(%2)")
1966 [(set (match_operand:DI 0 "register_operand" "=r")
1967 (match_operand:DI 1 "immediate_operand" "n"))]
1969 "* return output_load_const_dimode (operands);"
1970 [(set_attr "type" "marith")
1971 (set_attr "length" "4")]) ; length is 2, 3 or 4.
1973 ;; DFmode move instructions
1975 (define_expand "movdf"
1976 [(set (match_operand:DF 0 "general_operand" "")
1977 (match_operand:DF 1 "general_operand" ""))]
1981 if (emit_move_sequence (operands, DFmode, 0))
1986 [(set (match_operand:DF 0 "register_operand" "=r")
1987 (match_operand:DF 1 "register_operand" "r"))]
1989 && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
1990 && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
1991 [(set (match_dup 2) (match_dup 3))
1992 (set (match_dup 4) (match_dup 5))]
1994 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1995 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1996 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1997 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1999 ;; @@ This pattern is incomplete and doesn't appear necessary.
2001 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2002 ;; to be reloaded by putting the constant into memory.
2003 ;; It must come before the more general movdf pattern.
2006 ; [(set (match_operand:DF 0 "general_operand" "=r,o")
2007 ; (match_operand:DF 1 "" "G,G"))]
2008 ; "GET_CODE (operands[1]) == CONST_DOUBLE"
2011 ; switch (which_alternative)
2014 ; return \"or %0,%#r0,0\;or %d0,%#r0,0\";
2016 ; operands[1] = adjust_address (operands[0], SImode, 4);
2017 ; return \"%v0st\\t %#r0,%0\;st %#r0,%1\";
2022 [(set (match_operand:DF 0 "register_operand" "=r,x")
2026 or %0,%#r0,0\;or %d0,%#r0,0
2028 [(set_attr "type" "marith,mov")])
2031 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2032 (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2035 or %0,%#r0,%1\;or %d0,%#r0,%d1
2043 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2046 [(set (match_operand:DF 0 "register_operand" "=r")
2047 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2048 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2050 "or %0,%1,%#lo16(%2)")
2053 [(set (match_operand:DF 0 "register_operand" "=r")
2054 (match_operand:DF 1 "immediate_operand" "F"))]
2056 "* return output_load_const_double (operands);"
2057 [(set_attr "type" "marith")
2058 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2060 ;; SFmode move instructions
2062 (define_expand "movsf"
2063 [(set (match_operand:SF 0 "general_operand" "")
2064 (match_operand:SF 1 "general_operand" ""))]
2068 if (emit_move_sequence (operands, SFmode, 0))
2072 ;; @@ What happens to fconst0_rtx?
2074 [(set (match_operand:SF 0 "register_operand" "=r,x")
2080 [(set_attr "type" "arith,mov")])
2083 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2084 (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2095 [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2098 [(set (match_operand:SF 0 "register_operand" "=r")
2099 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2100 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2102 "or %0,%1,%#lo16(%2)")
2105 [(set (match_operand:SF 0 "register_operand" "=r")
2106 (match_operand:SF 1 "immediate_operand" "F"))]
2107 "operands[1] != const0_rtx"
2108 "* return output_load_const_float (operands);"
2109 [(set_attr "type" "marith")]) ; length is 1 or 2.
2111 ;; String/block move insn. See m88k.c for details.
2113 (define_expand "movstrsi"
2114 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2115 (mem:BLK (match_operand:BLK 1 "" "")))
2116 (use (match_operand:SI 2 "arith32_operand" ""))
2117 (use (match_operand:SI 3 "immediate_operand" ""))])]
2121 rtx dest_mem = operands[0];
2122 rtx src_mem = operands[1];
2123 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2124 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2125 expand_block_move (dest_mem, src_mem, operands);
2129 ;; ??? We shouldn't be allowing such mode mismatches
2131 [(set (match_operand 0 "register_operand" "=r")
2132 (match_operand:BLK 1 "memory_operand" "m"))]
2136 switch (GET_MODE (operands[0]))
2139 return \"%V1ld.bu\\t %0,%1\";
2141 return \"%V1ld.hu\\t %0,%1\";
2143 return \"%V1ld\\t %0,%1\";
2145 return \"%V1ld.d\\t %0,%1\";
2150 [(set_attr "type" "load")])
2153 [(set (match_operand:BLK 0 "memory_operand" "=m")
2154 (match_operand 1 "register_operand" "r"))]
2158 switch (GET_MODE (operands[1]))
2161 return \"%v0st.b\\t %1,%0\";
2163 return \"%v0st.h\\t %1,%0\";
2165 return \"%v0st\\t %1,%0\";
2167 return \"%v0st.d\\t %1,%0\";
2172 [(set_attr "type" "store")])
2174 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2175 ;; operand 0 is the function name
2176 ;; operand 1 is the destination pointer
2177 ;; operand 2 is the source pointer
2178 ;; operand 3 is the offset for the source and destination pointers
2179 ;; operand 4 is the first value to be loaded
2180 ;; operand 5 is the register to hold the value (r4 or r5)
2182 (define_expand "call_block_move"
2183 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2184 (match_operand:SI 3 "immediate_operand" "")))
2185 (set (match_operand 5 "register_operand" "")
2186 (match_operand 4 "memory_operand" ""))
2187 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2192 (parallel [(set (reg:DI 2)
2193 (call (mem:SI (match_operand 0 "" ""))
2195 (clobber (reg:SI 1))])]
2199 ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2200 ;; operands 0-5 as in the non-looping interface
2201 ;; operand 6 is the loop count
2203 (define_expand "call_movstrsi_loop"
2204 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2205 (match_operand:SI 3 "immediate_operand" "")))
2206 (set (match_operand:SI 5 "register_operand" "")
2207 (match_operand 4 "memory_operand" ""))
2208 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2210 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2215 (parallel [(set (reg:DI 2)
2216 (call (mem:SI (match_operand 0 "" ""))
2218 (clobber (reg:SI 1))])]
2222 ;;- zero extension instructions
2224 (define_expand "zero_extendhisi2"
2225 [(set (match_operand:SI 0 "register_operand" "")
2226 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2230 if (GET_CODE (operands[1]) == MEM
2231 && symbolic_address_p (XEXP (operands[1], 0)))
2233 = legitimize_address (flag_pic, operands[1], 0, 0);
2237 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2238 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2239 "GET_CODE (operands[1]) != CONST_INT"
2244 [(set_attr "type" "arith,arith,load")])
2246 (define_expand "zero_extendqihi2"
2247 [(set (match_operand:HI 0 "register_operand" "")
2248 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2252 if (GET_CODE (operands[1]) == MEM
2253 && symbolic_address_p (XEXP (operands[1], 0)))
2255 = legitimize_address (flag_pic, operands[1], 0, 0);
2259 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2260 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2261 "GET_CODE (operands[1]) != CONST_INT"
2266 [(set_attr "type" "arith,arith,load")])
2268 (define_expand "zero_extendqisi2"
2269 [(set (match_operand:SI 0 "register_operand" "")
2270 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2274 if (GET_CODE (operands[1]) == MEM
2275 && symbolic_address_p (XEXP (operands[1], 0)))
2278 = legitimize_address (flag_pic, operands[1], 0, 0);
2279 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2280 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
2286 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2287 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2288 "GET_CODE (operands[1]) != CONST_INT"
2293 [(set_attr "type" "arith,arith,load")])
2295 ;;- sign extension instructions
2297 (define_expand "extendsidi2"
2298 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 4)
2299 (match_operand:SI 1 "general_operand" "g"))
2300 (set (subreg:SI (match_dup 0) 0)
2301 (ashiftrt:SI (subreg:SI (match_dup 0) 4)
2306 (define_expand "extendhisi2"
2307 [(set (match_operand:SI 0 "register_operand" "")
2308 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2312 if (GET_CODE (operands[1]) == MEM
2313 && symbolic_address_p (XEXP (operands[1], 0)))
2315 = legitimize_address (flag_pic, operands[1], 0, 0);
2319 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2320 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2321 "GET_CODE (operands[1]) != CONST_INT"
2327 [(set_attr "type" "bit,arith,arith,load")])
2329 (define_expand "extendqihi2"
2330 [(set (match_operand:HI 0 "register_operand" "")
2331 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2335 if (GET_CODE (operands[1]) == MEM
2336 && symbolic_address_p (XEXP (operands[1], 0)))
2338 = legitimize_address (flag_pic, operands[1], 0, 0);
2342 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2343 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2344 "GET_CODE (operands[1]) != CONST_INT"
2350 [(set_attr "type" "bit,arith,arith,load")])
2352 (define_expand "extendqisi2"
2353 [(set (match_operand:SI 0 "register_operand" "")
2354 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2358 if (GET_CODE (operands[1]) == MEM
2359 && symbolic_address_p (XEXP (operands[1], 0)))
2361 = legitimize_address (flag_pic, operands[1], 0, 0);
2365 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2366 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2367 "GET_CODE (operands[1]) != CONST_INT"
2373 [(set_attr "type" "bit,arith,arith,load")])
2375 ;; Conversions between float and double.
2377 ;; The fadd instruction does not conform to IEEE 754 when used to
2378 ;; convert between float and double. In particular, the sign of -0 is
2379 ;; not preserved. Interestingly, fsub does conform.
2381 (define_expand "extendsfdf2"
2382 [(set (match_operand:DF 0 "register_operand" "=r")
2383 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2388 [(set (match_operand:DF 0 "register_operand" "=r")
2389 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2391 "fsub.dss %0,%1,%#r0"
2392 [(set_attr "type" "spadd")])
2395 [(set (match_operand:DF 0 "register_operand" "=r,x")
2396 (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2399 [(set_attr "type" "spadd")])
2401 (define_expand "truncdfsf2"
2402 [(set (match_operand:SF 0 "register_operand" "=r")
2403 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2408 [(set (match_operand:SF 0 "register_operand" "=r")
2409 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2411 "fsub.sds %0,%1,%#r0"
2412 [(set_attr "type" "dpadd")])
2415 [(set (match_operand:SF 0 "register_operand" "=r,x")
2416 (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2419 [(set_attr "type" "dpadd")])
2421 ;; Conversions between floating point and integer
2423 (define_insn "floatsidf2"
2424 [(set (match_operand:DF 0 "register_operand" "=r,x")
2425 (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2428 [(set_attr "type" "spadd,dpadd")])
2430 (define_insn "floatsisf2"
2431 [(set (match_operand:SF 0 "register_operand" "=r,x")
2432 (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2435 [(set_attr "type" "spadd,spadd")])
2437 (define_insn "fix_truncdfsi2"
2438 [(set (match_operand:SI 0 "register_operand" "=r,r")
2439 (fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2442 [(set_attr "type" "dpadd,dpadd")])
2444 (define_insn "fix_truncsfsi2"
2445 [(set (match_operand:SI 0 "register_operand" "=r,r")
2446 (fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2449 [(set_attr "type" "spadd,dpadd")])
2452 ;;- arithmetic instructions
2453 ;;- add instructions
2455 (define_insn "addsi3"
2456 [(set (match_operand:SI 0 "register_operand" "=r,r")
2457 (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2458 (match_operand:SI 2 "add_operand" "rI,J")))]
2464 ;; patterns for mixed mode floating point.
2465 ;; Do not define patterns that utilize mixed mode arithmetic that result
2466 ;; in narrowing the precision, because it loses accuracy, since the standard
2467 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2469 (define_expand "adddf3"
2470 [(set (match_operand:DF 0 "register_operand" "=r,x")
2471 (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2472 (match_operand:DF 2 "general_operand" "r,x")))]
2476 operands[1] = legitimize_operand (operands[1], DFmode);
2477 operands[2] = legitimize_operand (operands[2], DFmode);
2481 [(set (match_operand:DF 0 "register_operand" "=r,x")
2482 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2483 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2486 [(set_attr "type" "spadd")])
2489 [(set (match_operand:DF 0 "register_operand" "=r,x")
2490 (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2491 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2494 [(set_attr "type" "dpadd")])
2497 [(set (match_operand:DF 0 "register_operand" "=r,x")
2498 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2499 (match_operand:DF 2 "register_operand" "r,x")))]
2502 [(set_attr "type" "dpadd")])
2505 [(set (match_operand:DF 0 "register_operand" "=r,x")
2506 (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2507 (match_operand:DF 2 "register_operand" "r,x")))]
2510 [(set_attr "type" "dpadd")])
2512 (define_insn "addsf3"
2513 [(set (match_operand:SF 0 "register_operand" "=r,x")
2514 (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2515 (match_operand:SF 2 "register_operand" "r,x")))]
2518 [(set_attr "type" "spadd")])
2521 [(set (match_operand:DI 0 "register_operand" "=r")
2522 (plus:DI (match_operand:DI 1 "register_operand" "r")
2524 (match_operand:SI 2 "register_operand" "r"))))
2525 (clobber (reg:CC 0))]
2527 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2528 [(set_attr "type" "marith")])
2531 [(set (match_operand:DI 0 "register_operand" "=r")
2532 (plus:DI (zero_extend:DI
2533 (match_operand:SI 1 "register_operand" "r"))
2534 (match_operand:DI 2 "register_operand" "r")))
2535 (clobber (reg:CC 0))]
2537 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2538 [(set_attr "type" "marith")])
2540 (define_insn "adddi3"
2541 [(set (match_operand:DI 0 "register_operand" "=r")
2542 (plus:DI (match_operand:DI 1 "register_operand" "%r")
2543 (match_operand:DI 2 "register_operand" "r")))
2544 (clobber (reg:CC 0))]
2546 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2547 [(set_attr "type" "marith")])
2549 ;; Add with carry insns.
2552 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2553 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2554 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2556 (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2558 "addu.co %r0,%r1,%r2")
2561 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2562 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2565 "addu.co %#r0,%r0,%r1")
2568 [(set (match_operand:SI 0 "register_operand" "=r")
2569 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2570 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2573 "addu.ci %r0,%r1,%r2")
2575 ;;- subtract instructions
2577 (define_insn "subsi3"
2578 [(set (match_operand:SI 0 "register_operand" "=r")
2579 (minus:SI (match_operand:SI 1 "register_operand" "r")
2580 (match_operand:SI 2 "arith32_operand" "rI")))]
2584 ;; patterns for mixed mode floating point
2585 ;; Do not define patterns that utilize mixed mode arithmetic that result
2586 ;; in narrowing the precision, because it loses accuracy, since the standard
2587 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2589 (define_expand "subdf3"
2590 [(set (match_operand:DF 0 "register_operand" "=r,x")
2591 (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2592 (match_operand:DF 2 "general_operand" "r,x")))]
2596 operands[1] = legitimize_operand (operands[1], DFmode);
2597 operands[2] = legitimize_operand (operands[2], DFmode);
2601 [(set (match_operand:DF 0 "register_operand" "=r,x")
2602 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2603 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2606 [(set_attr "type" "spadd")])
2609 [(set (match_operand:DF 0 "register_operand" "=r,x")
2610 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2611 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2614 [(set_attr "type" "dpadd")])
2617 [(set (match_operand:DF 0 "register_operand" "=r,x")
2618 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2619 (match_operand:DF 2 "register_operand" "r,x")))]
2622 [(set_attr "type" "dpadd")])
2625 [(set (match_operand:DF 0 "register_operand" "=r,x")
2626 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2627 (match_operand:DF 2 "register_operand" "r,x")))]
2630 [(set_attr "type" "dpadd")])
2632 (define_insn "subsf3"
2633 [(set (match_operand:SF 0 "register_operand" "=r,x")
2634 (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2635 (match_operand:SF 2 "register_operand" "r,x")))]
2638 [(set_attr "type" "spadd")])
2641 [(set (match_operand:DI 0 "register_operand" "=r")
2642 (minus:DI (match_operand:DI 1 "register_operand" "r")
2644 (match_operand:SI 2 "register_operand" "r"))))
2645 (clobber (reg:CC 0))]
2647 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2648 [(set_attr "type" "marith")])
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (minus:DI (zero_extend:DI
2653 (match_operand:SI 1 "register_operand" "r"))
2654 (match_operand:DI 2 "register_operand" "r")))
2655 (clobber (reg:CC 0))]
2657 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2658 [(set_attr "type" "marith")])
2660 (define_insn "subdi3"
2661 [(set (match_operand:DI 0 "register_operand" "=r")
2662 (minus:DI (match_operand:DI 1 "register_operand" "r")
2663 (match_operand:DI 2 "register_operand" "r")))
2664 (clobber (reg:CC 0))]
2666 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2667 [(set_attr "type" "marith")])
2669 ;; Subtract with carry insns.
2672 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
2673 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2674 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2676 (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2678 "subu.co %r0,%r1,%r2")
2681 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2682 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2685 "subu.co %#r0,%r0,%r1")
2688 [(set (match_operand:SI 0 "register_operand" "=r")
2689 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2690 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2693 "subu.ci %r0,%r1,%r2")
2695 ;;- multiply instructions
2697 ;; There is an unfounded silicon errata for E.1 requiring that an
2698 ;; immediate constant value in div/divu/mul instructions be less than
2699 ;; 0x800. This is no longer provided for.
2701 (define_insn "mulsi3"
2702 [(set (match_operand:SI 0 "register_operand" "=r")
2703 (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2704 (match_operand:SI 2 "arith32_operand" "rI")))]
2707 [(set_attr "type" "imul")])
2709 (define_insn "umulsidi3"
2710 [(set (match_operand:DI 0 "register_operand" "=r")
2711 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2712 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2715 [(set_attr "type" "imul")])
2717 ;; patterns for mixed mode floating point
2718 ;; Do not define patterns that utilize mixed mode arithmetic that result
2719 ;; in narrowing the precision, because it loses accuracy, since the standard
2720 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2722 (define_expand "muldf3"
2723 [(set (match_operand:DF 0 "register_operand" "=r,x")
2724 (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2725 (match_operand:DF 2 "general_operand" "r,x")))]
2729 operands[1] = legitimize_operand (operands[1], DFmode);
2730 operands[2] = legitimize_operand (operands[2], DFmode);
2734 [(set (match_operand:DF 0 "register_operand" "=r,x")
2735 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2736 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2739 [(set_attr "type" "spmul")])
2742 [(set (match_operand:DF 0 "register_operand" "=r,x")
2743 (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2744 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2747 [(set_attr "type" "spmul")])
2750 [(set (match_operand:DF 0 "register_operand" "=r,x")
2751 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2752 (match_operand:DF 2 "register_operand" "r,x")))]
2755 [(set_attr "type" "spmul")])
2758 [(set (match_operand:DF 0 "register_operand" "=r,x")
2759 (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2760 (match_operand:DF 2 "register_operand" "r,x")))]
2763 [(set_attr "type" "dpmul")])
2765 (define_insn "mulsf3"
2766 [(set (match_operand:SF 0 "register_operand" "=r,x")
2767 (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2768 (match_operand:SF 2 "register_operand" "r,x")))]
2771 [(set_attr "type" "spmul")])
2773 ;;- divide instructions
2775 ;; The 88k div and divu instructions don't reliably trap on
2776 ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The
2777 ;; general scheme for doing divide is to do a 4-way split based on the
2778 ;; sign of the two operand and do the appropriate negates.
2780 ;; The conditional trap instruction is not used as this serializes the
2781 ;; processor. Instead a conditional branch and an unconditional trap
2782 ;; are used, but after the divu. Since the divu takes up to 38 cycles,
2783 ;; the conditional branch is essentially free.
2785 ;; Two target options control how divide is done. One options selects
2786 ;; whether to do the branch and negate scheme instead of using the div
2787 ;; instruction; the other option selects whether to explicitly check
2788 ;; for divide-by-zero or take your chances. If the div instruction is
2789 ;; used, the O/S must complete the operation if the operands are
2790 ;; negative. The O/S will signal an overflow condition if the most
2791 ;; negative number (-2147483648) is divided by negative 1.
2793 ;; There is an unfounded silicon errata for E.1 requiring that an
2794 ;; immediate constant value in div/divu/mul instructions be less than
2795 ;; 0x800. This is no longer provided for.
2797 ;; Division by 0 trap
2798 (define_insn "trap_divide_by_zero"
2799 [(trap_if (const_int 1) (const_int 503))]
2802 [(set_attr "type" "weird")])
2804 ;; Conditional division by 0 trap.
2805 (define_expand "tcnd_divide_by_zero"
2807 (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2810 (match_operand 1 "" "")))
2811 (trap_if (const_int 1) (const_int 503))]
2815 emit_insn (gen_cmpsi (operands[0], const0_rtx));
2816 emit_jump_insn (gen_bne (operands[1]));
2817 emit_insn (gen_trap_divide_by_zero ());
2821 (define_expand "divsi3"
2822 [(set (match_operand:SI 0 "register_operand" "")
2823 (div:SI (match_operand:SI 1 "arith32_operand" "")
2824 (match_operand:SI 2 "arith32_operand" "")))]
2828 rtx op0 = operands[0];
2829 rtx op1 = operands[1];
2830 rtx op2 = operands[2];
2833 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making
2834 it a runtime (perhaps quite special). */
2836 if (GET_CODE (op1) == CONST_INT)
2837 op1 = force_reg (SImode, op1);
2839 else if (GET_CODE (op2) == CONST_INT
2840 && ! SMALL_INT (operands[2]))
2841 op2 = force_reg (SImode, op2);
2843 if (op2 == const0_rtx)
2845 emit_insn (gen_trap_divide_by_zero ());
2846 emit_insn (gen_dummy (op0));
2852 emit_move_insn (op0, gen_rtx_DIV (SImode, op1, op2));
2853 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2855 rtx label = gen_label_rtx ();
2856 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2858 emit_insn (gen_dummy (op0));
2863 join_label = gen_label_rtx ();
2864 if (GET_CODE (op1) == CONST_INT)
2867 rtx neg_op2 = gen_reg_rtx (SImode);
2868 rtx label1 = gen_label_rtx ();
2870 if (INTVAL (op1) < 0)
2873 op1 = GEN_INT (-INTVAL (op1));
2875 op1 = force_reg (SImode, op1);
2877 emit_insn (gen_negsi2 (neg_op2, op2));
2878 emit_insn (gen_cmpsi (op2, const0_rtx));
2879 emit_jump_insn (gen_bgt (label1));
2880 /* constant / 0-or-negative */
2881 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2883 emit_insn (gen_negsi2 (op0, op0));
2885 if (TARGET_CHECK_ZERO_DIV)
2886 emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2887 emit_jump_insn (gen_jump (join_label));
2890 emit_label (label1); /* constant / positive */
2891 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2893 emit_insn (gen_negsi2 (op0, op0));
2896 else if (GET_CODE (op2) == CONST_INT)
2899 rtx neg_op1 = gen_reg_rtx (SImode);
2900 rtx label1 = gen_label_rtx ();
2902 if (INTVAL (op2) < 0)
2905 op2 = GEN_INT (-INTVAL (op2));
2907 else if (! SMALL_INT (operands[2]))
2908 op2 = force_reg (SImode, op2);
2910 emit_insn (gen_negsi2 (neg_op1, op1));
2911 emit_insn (gen_cmpsi (op1, const0_rtx));
2912 emit_jump_insn (gen_bge (label1));
2913 /* 0-or-negative / constant */
2914 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2916 emit_insn (gen_negsi2 (op0, op0));
2918 emit_jump_insn (gen_jump (join_label));
2921 emit_label (label1); /* positive / constant */
2922 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2924 emit_insn (gen_negsi2 (op0, op0));
2929 rtx neg_op1 = gen_reg_rtx (SImode);
2930 rtx neg_op2 = gen_reg_rtx (SImode);
2931 rtx label1 = gen_label_rtx ();
2932 rtx label2 = gen_label_rtx ();
2933 rtx label3 = gen_label_rtx ();
2934 rtx label4 = NULL_RTX;
2936 emit_insn (gen_negsi2 (neg_op2, op2));
2937 emit_insn (gen_cmpsi (op2, const0_rtx));
2938 emit_jump_insn (gen_bgt (label1));
2940 emit_insn (gen_negsi2 (neg_op1, op1));
2941 emit_insn (gen_cmpsi (op1, const0_rtx));
2942 emit_jump_insn (gen_bge (label2));
2943 /* negative / negative-or-0 */
2944 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, neg_op2));
2946 if (TARGET_CHECK_ZERO_DIV)
2948 label4 = gen_label_rtx ();
2949 emit_insn (gen_cmpsi (op2, const0_rtx));
2950 emit_jump_insn (gen_bne (join_label));
2951 emit_label (label4);
2952 emit_insn (gen_trap_divide_by_zero ());
2954 emit_jump_insn (gen_jump (join_label));
2957 emit_label (label2); /* pos.-or-0 / neg.-or-0 */
2958 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, neg_op2));
2960 if (TARGET_CHECK_ZERO_DIV)
2962 emit_insn (gen_cmpsi (op2, const0_rtx));
2963 emit_jump_insn (gen_beq (label4));
2966 emit_insn (gen_negsi2 (op0, op0));
2967 emit_jump_insn (gen_jump (join_label));
2970 emit_label (label1);
2971 emit_insn (gen_negsi2 (neg_op1, op1));
2972 emit_insn (gen_cmpsi (op1, const0_rtx));
2973 emit_jump_insn (gen_bge (label3));
2974 /* negative / positive */
2975 emit_move_insn (op0, gen_rtx_UDIV (SImode, neg_op1, op2));
2976 emit_insn (gen_negsi2 (op0, op0));
2977 emit_jump_insn (gen_jump (join_label));
2980 emit_label (label3); /* positive-or-0 / positive */
2981 emit_move_insn (op0, gen_rtx_UDIV (SImode, op1, op2));
2984 emit_label (join_label);
2986 emit_insn (gen_dummy (op0));
2991 [(set (match_operand:SI 0 "register_operand" "=r")
2992 (div:SI (match_operand:SI 1 "register_operand" "r")
2993 (match_operand:SI 2 "arith_operand" "rI")))]
2996 [(set_attr "type" "idiv")])
2998 (define_expand "udivsi3"
2999 [(set (match_operand:SI 0 "register_operand" "")
3000 (udiv:SI (match_operand:SI 1 "register_operand" "")
3001 (match_operand:SI 2 "arith32_operand" "")))]
3005 rtx op2 = operands[2];
3007 if (op2 == const0_rtx)
3009 emit_insn (gen_trap_divide_by_zero ());
3010 emit_insn (gen_dummy (operands[0]));
3013 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3015 rtx label = gen_label_rtx ();
3016 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3017 gen_rtx_UDIV (SImode, operands[1], op2)));
3018 emit_insn (gen_tcnd_divide_by_zero (op2, label));
3020 emit_insn (gen_dummy (operands[0]));
3026 [(set (match_operand:SI 0 "register_operand" "=r")
3027 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3028 (match_operand:SI 2 "arith32_operand" "rI")))]
3029 "operands[2] != const0_rtx"
3031 [(set_attr "type" "idiv")])
3034 [(set (match_operand:SI 0 "register_operand" "=r")
3035 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3039 [(set_attr "type" "weird")])
3041 ;; patterns for mixed mode floating point.
3042 ;; Do not define patterns that utilize mixed mode arithmetic that result
3043 ;; in narrowing the precision, because it loses accuracy, since the standard
3044 ;; requires double rounding, whereas the 88000 instruction only rounds once.
3046 (define_expand "divdf3"
3047 [(set (match_operand:DF 0 "register_operand" "=r,x")
3048 (div:DF (match_operand:DF 1 "general_operand" "r,x")
3049 (match_operand:DF 2 "general_operand" "r,x")))]
3053 operands[1] = legitimize_operand (operands[1], DFmode);
3054 if (real_power_of_2_operand (operands[2], DFmode))
3057 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3058 if (!exact_real_inverse (DFmode, &r))
3060 emit_insn (gen_muldf3 (operands[0], operands[1],
3061 CONST_DOUBLE_FROM_REAL_VALUE (r, DFmode)));
3064 else if (! register_operand (operands[2], DFmode))
3065 operands[2] = force_reg (DFmode, operands[2]);
3069 [(set (match_operand:DF 0 "register_operand" "=r,x")
3070 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3071 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3074 [(set_attr "type" "dpdiv")])
3077 [(set (match_operand:DF 0 "register_operand" "=r,x")
3078 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3079 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3082 [(set_attr "type" "dpdiv")])
3085 [(set (match_operand:DF 0 "register_operand" "=r,x")
3086 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3087 (match_operand:DF 2 "register_operand" "r,x")))]
3090 [(set_attr "type" "dpdiv")])
3092 (define_insn "divsf3"
3093 [(set (match_operand:SF 0 "register_operand" "=r,x")
3094 (div:SF (match_operand:SF 1 "register_operand" "r,x")
3095 (match_operand:SF 2 "register_operand" "r,x")))]
3098 [(set_attr "type" "spdiv")])
3101 [(set (match_operand:DF 0 "register_operand" "=r,x")
3102 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3103 (match_operand:DF 2 "register_operand" "r,x")))]
3106 [(set_attr "type" "dpdiv")])
3108 ;; - remainder instructions, don't define, since the hardware doesn't have any
3109 ;; direct support, and GNU can synthesis them out of div/mul just fine.
3111 ;;- load effective address, must come after add, so that we favor using
3112 ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require
3113 ;; the data unit), and also future 88k chips might not support unscaled
3114 ;; lda instructions.
3117 [(set (match_operand:SI 0 "register_operand" "=r")
3118 (match_operand:SI 1 "address_operand" "p"))]
3119 "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
3123 [(set (match_operand:SI 0 "register_operand" "=r")
3124 (match_operand:HI 1 "address_operand" "p"))]
3127 [(set_attr "type" "loada")])
3130 [(set (match_operand:SI 0 "register_operand" "=r")
3131 (match_operand:SI 1 "address_operand" "p"))]
3134 [(set_attr "type" "loada")])
3137 [(set (match_operand:SI 0 "register_operand" "=r")
3138 (match_operand:DI 1 "address_operand" "p"))]
3141 [(set_attr "type" "loada")])
3144 [(set (match_operand:SI 0 "register_operand" "=r")
3145 (match_operand:SF 1 "address_operand" "p"))]
3148 [(set_attr "type" "loada")])
3151 [(set (match_operand:SI 0 "register_operand" "=r")
3152 (match_operand:DF 1 "address_operand" "p"))]
3155 [(set_attr "type" "loada")])
3157 ;;- and instructions (with complement also)
3159 [(set (match_operand:SI 0 "register_operand" "=r")
3160 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3161 (match_operand:SI 2 "register_operand" "r")))]
3165 ;; If the operation is being performed on a 32-bit constant such that
3166 ;; it cannot be done in one insn, do it in two. We may lose a bit on
3167 ;; CSE in pathological cases, but it seems better doing it this way.
3169 (define_expand "andsi3"
3170 [(set (match_operand:SI 0 "register_operand" "")
3171 (and:SI (match_operand:SI 1 "arith32_operand" "")
3172 (match_operand:SI 2 "arith32_operand" "")))]
3176 if (GET_CODE (operands[2]) == CONST_INT)
3178 int value = INTVAL (operands[2]);
3180 if (! (SMALL_INTVAL (value)
3181 || (value & 0xffff0000) == 0xffff0000
3182 || (value & 0xffff) == 0xffff
3183 || (value & 0xffff) == 0
3184 || integer_ok_for_set (~value)))
3186 emit_insn (gen_andsi3 (operands[0], operands[1],
3187 GEN_INT (value | 0xffff)));
3188 operands[1] = operands[0];
3189 operands[2] = GEN_INT (value | 0xffff0000);
3195 [(set (match_operand:SI 0 "register_operand" "=r,r")
3196 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3197 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3199 "* return output_and (operands);"
3200 [(set_attr "type" "arith,marith")])
3203 [(set (match_operand:DI 0 "register_operand" "=r")
3204 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3205 (match_operand:DI 2 "register_operand" "r")))]
3207 "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3208 [(set_attr "type" "marith")])
3210 (define_insn "anddi3"
3211 [(set (match_operand:DI 0 "register_operand" "=r")
3212 (and:DI (match_operand:DI 1 "arith64_operand" "%r")
3213 (match_operand:DI 2 "arith64_operand" "rn")))]
3219 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3220 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3221 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3223 output_asm_insn (output_and (xoperands), xoperands);
3225 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3226 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3227 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3229 return output_and (operands);
3231 [(set_attr "type" "marith")
3232 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3234 ;;- Bit set (inclusive or) instructions (with complement also)
3236 [(set (match_operand:SI 0 "register_operand" "=r")
3237 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3238 (match_operand:SI 2 "register_operand" "r")))]
3242 (define_expand "iorsi3"
3243 [(set (match_operand:SI 0 "register_operand" "")
3244 (ior:SI (match_operand:SI 1 "arith32_operand" "")
3245 (match_operand:SI 2 "arith32_operand" "")))]
3249 if (GET_CODE (operands[2]) == CONST_INT)
3251 int value = INTVAL (operands[2]);
3253 if (! (SMALL_INTVAL (value)
3254 || (value & 0xffff) == 0
3255 || integer_ok_for_set (value)))
3257 emit_insn (gen_iorsi3 (operands[0], operands[1],
3258 GEN_INT (value & 0xffff0000)));
3259 operands[1] = operands[0];
3260 operands[2] = GEN_INT (value & 0xffff);
3266 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3267 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3268 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3274 or.u %0,%1,%X2\;or %0,%0,%x2"
3275 [(set_attr "type" "arith,arith,bit,marith")])
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3280 (match_operand:DI 2 "register_operand" "r")))]
3282 "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3283 [(set_attr "type" "marith")])
3285 (define_insn "iordi3"
3286 [(set (match_operand:DI 0 "register_operand" "=r")
3287 (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3288 (match_operand:DI 2 "arith64_operand" "rn")))]
3294 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3295 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3296 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3298 output_asm_insn (output_ior (xoperands), xoperands);
3300 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3301 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3302 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3304 return output_ior (operands);
3306 [(set_attr "type" "marith")
3307 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3309 ;;- xor instructions (with complement also)
3311 [(set (match_operand:SI 0 "register_operand" "=r")
3312 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3313 (match_operand:SI 2 "register_operand" "r"))))]
3317 (define_expand "xorsi3"
3318 [(set (match_operand:SI 0 "register_operand" "")
3319 (xor:SI (match_operand:SI 1 "arith32_operand" "")
3320 (match_operand:SI 2 "arith32_operand" "")))]
3324 if (GET_CODE (operands[2]) == CONST_INT)
3326 int value = INTVAL (operands[2]);
3328 if (! (SMALL_INTVAL (value)
3329 || (value & 0xffff) == 0))
3331 emit_insn (gen_xorsi3 (operands[0], operands[1],
3332 GEN_INT (value & 0xffff0000)));
3333 operands[1] = operands[0];
3334 operands[2] = GEN_INT (value & 0xffff);
3340 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3341 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3342 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3347 xor.u %0,%1,%X2\;xor %0,%0,%x2"
3348 [(set_attr "type" "arith,arith,marith")])
3351 [(set (match_operand:DI 0 "register_operand" "=r")
3352 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3353 (match_operand:DI 2 "register_operand" "r"))))]
3355 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3356 [(set_attr "type" "marith")])
3358 (define_insn "xordi3"
3359 [(set (match_operand:DI 0 "register_operand" "=r")
3360 (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3361 (match_operand:DI 2 "arith64_operand" "rn")))]
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);
3371 output_asm_insn (output_xor (xoperands), xoperands);
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);
3377 return output_xor (operands);
3379 [(set_attr "type" "marith")
3380 (set_attr "length" "4")]) ; length is 2, 3, or 4.
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")))]
3389 (define_insn "one_cmpldi2"
3390 [(set (match_operand:DI 0 "register_operand" "=r")
3391 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3393 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3394 [(set_attr "type" "marith")])
3396 ;; Optimized special cases of shifting.
3397 ;; Must precede the general case.
3399 ;; @@ What about HImode shifted by 8?
3402 [(set (match_operand:SI 0 "register_operand" "=r")
3403 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3405 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3407 [(set_attr "type" "load")])
3410 [(set (match_operand:SI 0 "register_operand" "=r")
3411 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3413 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3415 [(set_attr "type" "load")])
3418 [(set (match_operand:SI 0 "register_operand" "=r")
3419 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3421 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3423 [(set_attr "type" "load")])
3426 [(set (match_operand:SI 0 "register_operand" "=r")
3427 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3429 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3431 [(set_attr "type" "load")])
3433 ;;- arithmetic shift instructions.
3435 ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should
3436 ;; be arith32_operand?
3438 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3440 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3441 (match_operand:SI 1 "arith_operand" "rI"))
3445 [(set_attr "type" "weird")])
3447 ;; Just in case the optimizer decides to fold away the test.
3449 [(trap_if (const_int 1) (const_int 7))]
3452 [(set_attr "type" "weird")])
3454 (define_expand "ashlsi3"
3455 [(set (match_operand:SI 0 "register_operand" "")
3456 (ashift:SI (match_operand:SI 1 "register_operand" "")
3457 (match_operand:SI 2 "arith32_operand" "")))]
3461 if (GET_CODE (operands[2]) == CONST_INT)
3463 if ((unsigned) INTVAL (operands[2]) > 31)
3465 if (TARGET_TRAP_LARGE_SHIFT)
3466 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3469 emit_move_insn (operands[0], const0_rtx);
3474 else if (TARGET_TRAP_LARGE_SHIFT)
3475 emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3477 else if (TARGET_HANDLE_LARGE_SHIFT)
3479 rtx reg = gen_reg_rtx (SImode);
3480 emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3481 emit_insn (gen_sleu (reg));
3482 emit_insn (gen_andsi3 (reg, operands[1], reg));
3488 [(set (match_operand:SI 0 "register_operand" "=r,r")
3489 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3490 (match_operand:SI 2 "arith5_operand" "r,K")))]
3495 [(set_attr "type" "bit")])
3497 (define_expand "ashrsi3"
3498 [(set (match_operand:SI 0 "register_operand" "")
3499 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3500 (match_operand:SI 2 "arith32_operand" "")))]
3504 if (GET_CODE (operands[2]) == CONST_INT)
3506 if ((unsigned) INTVAL (operands[2]) > 31)
3508 if (TARGET_TRAP_LARGE_SHIFT)
3510 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3515 operands[2] = GEN_INT (31);
3519 else if (TARGET_TRAP_LARGE_SHIFT)
3520 emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3522 else if (TARGET_HANDLE_LARGE_SHIFT)
3524 rtx reg = gen_reg_rtx (SImode);
3525 emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3526 emit_insn (gen_sgtu (reg));
3527 emit_insn (gen_iorsi3 (reg, operands[2], reg));
3533 [(set (match_operand:SI 0 "register_operand" "=r,r")
3534 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3535 (match_operand:SI 2 "arith5_operand" "r,K")))]
3540 [(set_attr "type" "bit")])
3542 ;;- logical shift instructions. Logical shift left becomes arithmetic
3545 (define_expand "lshrsi3"
3546 [(set (match_operand:SI 0 "register_operand" "")
3547 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3548 (match_operand:SI 2 "arith32_operand" "")))]
3552 if (GET_CODE (operands[2]) == CONST_INT)
3554 if ((unsigned) INTVAL (operands[2]) > 31)
3556 if (TARGET_TRAP_LARGE_SHIFT)
3557 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3560 emit_move_insn (operands[0], const0_rtx);
3565 else if (TARGET_TRAP_LARGE_SHIFT)
3566 emit_insn (gen_tbnd (operands[2], GEN_INT (31)));
3568 else if (TARGET_HANDLE_LARGE_SHIFT)
3570 rtx reg = gen_reg_rtx (SImode);
3571 emit_insn (gen_cmpsi (operands[2], GEN_INT (31)));
3572 emit_insn (gen_sleu (reg));
3573 emit_insn (gen_andsi3 (reg, operands[1], reg));
3579 [(set (match_operand:SI 0 "register_operand" "=r,r")
3580 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3581 (match_operand:SI 2 "arith5_operand" "r,K")))]
3586 [(set_attr "type" "bit")])
3588 ;;- rotate instructions
3590 (define_expand "rotlsi3"
3591 [(set (match_operand:SI 0 "register_operand" "")
3592 (rotatert:SI (match_operand:SI 1 "register_operand" "")
3593 (match_operand:SI 2 "arith32_operand" "")))]
3597 if (GET_CODE (operands[2]) == CONST_INT
3598 && (unsigned) INTVAL (operands[2]) >= 32)
3599 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3602 rtx op = gen_reg_rtx (SImode);
3603 emit_insn (gen_negsi2 (op, operands[2]));
3608 (define_insn "rotrsi3"
3609 [(set (match_operand:SI 0 "register_operand" "=r")
3610 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3611 (match_operand:SI 2 "arith_operand" "rI")))]
3614 [(set_attr "type" "bit")])
3618 ;; The ff1 instruction searches from the most significant bit while ffs
3619 ;; searches from the least significant bit. The bit index and treatment of
3620 ;; zero also differ. This amazing sequence was discovered using the GNU
3623 (define_insn "ffssi2"
3624 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3625 (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3626 (clobber (reg:CC 0))
3627 (clobber (match_scratch:SI 2 "=r,X"))]
3630 subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3631 subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3632 [(set_attr "type" "marith")
3633 (set_attr "length" "4")])
3635 ;; Bit field instructions.
3638 [(set (match_operand:SI 0 "register_operand" "=r")
3639 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3646 [(set (match_operand:SI 0 "register_operand" "=r")
3647 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3648 (match_operand:SI 2 "int5_operand" "")
3649 (match_operand:SI 3 "int5_operand" "")))]
3653 operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3654 return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3656 [(set_attr "type" "bit")])
3659 [(set (match_operand:SI 0 "register_operand" "=r")
3660 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3666 (define_insn "extzv"
3667 [(set (match_operand:SI 0 "register_operand" "=r")
3668 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3669 (match_operand:SI 2 "int5_operand" "")
3670 (match_operand:SI 3 "int5_operand" "")))]
3674 operands[4] = GEN_INT ((32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3675 return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3677 [(set_attr "type" "bit")])
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" ""))
3687 operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3688 return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3690 [(set_attr "type" "bit")])
3693 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3694 (match_operand:SI 1 "int5_operand" "")
3695 (match_operand:SI 2 "int5_operand" ""))
3700 operands[3] = GEN_INT ((32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3701 return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3703 [(set_attr "type" "bit")])
3706 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3707 (match_operand:SI 1 "int5_operand" "")
3708 (match_operand:SI 2 "int5_operand" ""))
3709 (match_operand:SI 3 "int32_operand" "n"))]
3713 int value = INTVAL (operands[3]);
3715 if (INTVAL (operands[1]) < 32)
3716 value &= (1 << INTVAL (operands[1])) - 1;
3718 operands[2] = GEN_INT (32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3720 value <<= INTVAL (operands[2]);
3721 operands[3] = GEN_INT (value);
3723 if (SMALL_INTVAL (value))
3724 return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3725 else if ((value & 0x0000ffff) == 0)
3726 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3728 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3730 [(set_attr "type" "marith")
3731 (set_attr "length" "3")]) ; may be 2 or 3.
3734 (define_insn "negsi2"
3735 [(set (match_operand:SI 0 "register_operand" "=r")
3736 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3741 [(set (match_operand:SF 0 "register_operand" "=r,x")
3742 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3746 fsub.ssd %0,%#x0,%1"
3747 [(set_attr "type" "dpadd")])
3749 (define_insn "negdf2"
3750 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3751 (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3754 xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3756 [(set_attr "type" "marith,arith")])
3758 (define_insn "negsf2"
3759 [(set (match_operand:SF 0 "register_operand" "=r")
3760 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3762 "xor.u %0,%1,0x8000")
3764 ;; absolute value insns for floating-point (integer abs can be done using the
3765 ;; machine-independent sequence).
3767 (define_insn "absdf2"
3768 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3769 (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3772 and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3774 [(set_attr "type" "marith,arith")])
3776 (define_insn "abssf2"
3777 [(set (match_operand:SF 0 "register_operand" "=r")
3778 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3780 "and.u %0,%1,0x7fff")
3782 ;; Subroutines of "casesi".
3784 ;; Operand 0 is index
3785 ;; operand 1 is the minimum bound
3786 ;; operand 2 is the maximum bound - minimum bound + 1
3787 ;; operand 3 is CODE_LABEL for the table;
3788 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3790 (define_expand "casesi"
3791 ;; We don't use these for generating the RTL, but we must describe
3792 ;; the operands here.
3793 [(match_operand:SI 0 "general_operand" "")
3794 (match_operand:SI 1 "immediate_operand" "")
3795 (match_operand:SI 2 "immediate_operand" "")
3796 (match_operand 3 "" "")
3797 (match_operand 4 "" "")]
3801 register rtx index_diff = gen_reg_rtx (SImode);
3802 register rtx low = GEN_INT (-INTVAL (operands[1]));
3803 register rtx label = gen_rtx_LABEL_REF (Pmode, operands[3]);
3804 register rtx base = NULL_RTX;
3806 if (! CASE_VECTOR_INSNS)
3807 /* These instructions are likely to be scheduled and made loop invariant.
3808 This decreases the cost of the dispatch at the expense of the default
3810 base = force_reg (SImode, memory_address_noforce (SImode, label));
3812 /* Compute the index difference and handle the default case. */
3813 emit_insn (gen_addsi3 (index_diff,
3814 force_reg (SImode, operands[0]),
3815 ADD_INT (low) ? low : force_reg (SImode, low)));
3816 emit_insn (gen_cmpsi (index_diff, operands[2]));
3817 /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3818 entry to the table. However, that doesn't seem to win on the m88110. */
3819 emit_jump_insn (gen_bgtu (operands[4]));
3821 if (CASE_VECTOR_INSNS)
3822 /* Call the jump that will branch to the appropriate case. */
3823 emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3825 /* Load the table entry and jump to it. */
3826 emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3828 /* Claim that flow drops into the table so it will be adjacent by not
3829 emitting a barrier. */
3833 (define_expand "casesi_jump"
3834 [(set (match_operand:SI 0 "" "")
3835 (mem:SI (plus:SI (match_operand:SI 1 "" "")
3836 (mult:SI (match_operand:SI 2 "" "")
3838 (parallel [(set (pc) (match_dup 0))
3839 (use (label_ref (match_operand 3 "" "")))])]
3844 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3845 (use (label_ref (match_operand 1 "" "")))]
3848 [(set_attr "type" "jump")])
3850 ;; The bsr.n instruction is directed to the END of the table. See
3851 ;; ASM_OUTPUT_CASE_END.
3853 (define_insn "casesi_enter"
3854 [(set (pc) (match_operand 0 "" ""))
3855 (use (match_operand:SI 1 "register_operand" "r"))
3856 ;; The USE here is so that at least one jump-insn will refer to the label,
3857 ;; to keep it alive in jump_optimize.
3858 (use (label_ref (match_operand 2 "" "")))
3859 (clobber (reg:SI 1))]
3863 if (flag_delayed_branch)
3864 return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3865 m88k_case_index = REGNO (operands[1]);
3868 [(set_attr "type" "weird")
3869 (set_attr "length" "3")]) ; Including the "jmp r1".
3871 ;;- jump to subroutine
3872 (define_expand "call"
3873 [(parallel [(call (match_operand:SI 0 "" "")
3874 (match_operand 1 "" ""))
3875 (clobber (reg:SI 1))])]
3879 if (GET_CODE (operands[0]) == MEM
3880 && ! call_address_operand (XEXP (operands[0], 0), SImode))
3881 operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
3882 force_reg (Pmode, XEXP (operands[0], 0)));
3886 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3887 (match_operand 1 "" ""))
3888 (clobber (reg:SI 1))])]
3890 "* return output_call (operands, operands[0]);"
3891 [(set_attr "type" "call")])
3893 (define_expand "call_value"
3894 [(parallel [(set (match_operand 0 "register_operand" "")
3895 (call (match_operand:SI 1 "" "")
3896 (match_operand 2 "" "")))
3897 (clobber (reg:SI 1))])]
3901 if (GET_CODE (operands[1]) == MEM
3902 && ! call_address_operand (XEXP (operands[1], 0), SImode))
3903 operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
3904 force_reg (Pmode, XEXP (operands[1], 0)));
3908 [(parallel [(set (match_operand 0 "register_operand" "=r")
3910 (match_operand:SI 1 "call_address_operand" "rQ"))
3911 (match_operand 2 "" "")))
3912 (clobber (reg:SI 1))])]
3914 "* return output_call (operands, operands[1]);"
3915 [(set_attr "type" "call")])
3917 ;; Nop instruction and others
3923 [(set_attr "type" "bit")])
3925 (define_insn "return"
3929 [(set_attr "type" "jump")])
3931 (define_expand "prologue"
3934 "m88k_expand_prologue (); DONE;")
3936 (define_expand "epilogue"
3938 "! null_prologue ()"
3939 "m88k_expand_epilogue ();")
3941 (define_insn "blockage"
3942 [(unspec_volatile [(const_int 0)] 0)]
3945 [(set_attr "length" "0")])
3947 (define_insn "indirect_jump"
3948 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3951 [(set_attr "type" "jump")])
3955 (label_ref (match_operand 0 "" "")))]
3958 [(set_attr "type" "jump")])
3960 ;; This insn is used for some loop tests, typically loops reversed when
3961 ;; strength reduction is used. It is actually created when the instruction
3962 ;; combination phase combines the special loop test. Since this insn
3963 ;; is both a jump insn and has an output, it must deal with its own
3964 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
3965 ;; to not choose the register alternatives in the event a reload is needed.
3967 (define_expand "decrement_and_branch_until_zero"
3968 [(parallel [(set (pc)
3970 (match_operator 0 "relop_no_unsigned"
3971 [(match_operand:SI 1 "register_operand" "")
3973 (label_ref (match_operand 2 "" ""))
3976 (plus:SI (match_dup 1)
3977 (match_operand:SI 3 "add_operand" "")))
3978 (clobber (match_scratch:SI 4 ""))
3979 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])]
3986 (match_operator 0 "relop_no_unsigned"
3987 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
3989 (label_ref (match_operand 2 "" ""))
3992 (plus:SI (match_dup 1)
3993 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
3994 (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
3995 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
3996 "find_reg_note (insn, REG_NONNEG, 0)"
3998 bcnd.n %B0,%1,%2\;addu %1,%1,%3
3999 bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4000 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4001 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4002 [(set_attr "type" "weird")
4003 (set_attr "length" "2,2,4,4")])
4005 ;; Special insn to serve as the last insn of a define_expand. This insn
4006 ;; will generate no code.
4008 (define_expand "dummy"
4009 [(set (match_operand 0 "" "") (match_dup 0))]