1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;;; Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@mcc.com)
4 ;; Currently maintained by (gcc@dg-rtp.dg.com)
6 ;; This file is part of GNU CC.
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; RCS rev field. This is a NOP, just to get the RCS id into the
28 (define_expand "m88k_rcs_id"
29 [(match_operand:SI 0 "" "")]
31 "{ static char rcs_id[] = \"$What: <@(#) m88k.md,v 1.1.1.2.2.2> $\";
34 ;; Attribute describing the processor. This attribute must match exactly
35 ;; with the processor_type enumeration in m88k.h.
38 (define_attr "cpu" "m88100,m88110,m88000"
39 (const (symbol_ref "m88k_cpu")))
41 ; Type of each instruction. Default is arithmetic.
42 ; I'd like to write the list as this, but genattrtab won't accept it.
44 ; "branch,jump,call, ; flow-control instructions
45 ; load,store,loadd,loada, ; data unit instructions
46 ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
47 ; spmul,dpmul,imul, ; FPU multiply instructions
48 ; arith,bit,mov ; integer unit instructions
49 ; marith,weird" ; multi-word instructions
51 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
53 "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
54 (const_string "arith"))
56 (define_attr "fpu" "yes,no"
58 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
59 (const_string "yes") (const_string "no")))
61 ; Length in # of instructions of each insn. The values are not exact, but
63 (define_attr "length" ""
64 (cond [(eq_attr "type" "marith,weird,branch")
68 ; Describe a user's asm statement.
69 (define_asm_attributes
70 [(set_attr "type" "weird")])
72 ; Define the delay slot requirements for branches and calls.
73 ; The m88100 annuls instructions if a conditional branch is taken.
74 ; For insns of TYPE_BRANCH that are multi-word instructions, the
75 ; delay slot applies to the first instruction.
77 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
78 ; be a call or branch.
80 (define_delay (eq_attr "type" "branch,jump")
83 (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
84 (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
85 (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
86 (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
88 ; output_call supports an unconditional branch in the delay slot of
89 ; a call. (@@ Support for this case is expected in reorg.c soon.)
91 (define_delay (eq_attr "type" "call")
92 [(eq_attr "type" "!branch,call,marith,weird") ; required.
95 ; An abstract block diagram of the function units for the m88100.
102 ; ,----------'| | `----------------------.
104 ; load | store | | arith | | |
105 ; | | | +-v-v-+ | dp source
107 ; store | | | div +-v-v-+
108 ; ,------. | | | ,-----. ,-----------' `-----------.
110 ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+
111 ; | | stage 2 | | | `---| add 2 | | mul 2 |
112 ; | +---------+ | +--v--+ +-------+ imul +-------+
113 ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |
114 ; | +---------+ | +--v--+ +-------+ | +-------+
115 ; | | stage 0 | | | | add 4 | | | mul 4 |
116 ; | +--v---v--+ | | +---v---+ | +-------+
117 ; | | | | | | | | mul 5 |
118 ; | * | | | | | +---v---+
119 ; | | | | | +----v----+ |
120 ; | load | | | fp add `------>| fp last |<------' fp mul
121 ; | | | | +---v-v--^+
123 ; | | | | | `--' dp dest
124 ; | | +--v-----v--+ |
125 ; | `--->| writeback |<--------------------'
128 ; `------------------' *
130 ; The decode unit need not be specified.
131 ; Consideration of writeback contention is critical to superb scheduling.
133 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
134 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
136 ; Describing the '100 alu is currently not useful.
137 ;(define_function_unit "alu" 1 0 (eq_attr "type"
138 ; "!store,marith,weird") 1 0)
139 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
141 (define_function_unit "alu" 1 0
142 (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
143 (define_function_unit "alu" 1 0
144 (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
146 (define_function_unit "bit" 1 0
147 (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
149 (define_function_unit "mem100" 1 0
150 (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
151 (define_function_unit "mem100" 1 0
152 (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
153 (define_function_unit "mem100" 1 0
154 (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
156 (define_function_unit "mem110" 1 0
157 (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
158 (define_function_unit "mem110" 1 0
159 (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
161 ; The times are adjusted to include fp1 and fplast, but then are further
162 ; adjusted based on the actual generated code. The notation to the right
163 ; is the total latency. A range denotes a group of instructions and/or
164 ; conditions (the extra clock of fplast time with some sequences).
166 (define_function_unit "fpmul100" 1 0
167 (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8
168 (define_function_unit "fpmul100" 1 0
169 (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10
170 (define_function_unit "fpmul100" 1 0
171 (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4
173 (define_function_unit "fpmul110" 1 0
174 (and (eq_attr "type" "imul,spmul,dpmul")
175 (eq_attr "cpu" "!m88100")) 5 2) ; 3
177 (define_function_unit "fpadd100" 1 5
178 (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6
179 (define_function_unit "fpadd100" 1 5
180 (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7
182 (define_function_unit "fpadd110" 1 0
183 (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3
184 (define_function_unit "fpadd110" 1 0
185 (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1
187 (define_function_unit "fpadd100" 1 5
188 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31
189 (define_function_unit "fpadd100" 1 5
190 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61
191 (define_function_unit "fpadd100" 1 5
192 (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38
194 (define_function_unit "div" 1 1
195 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13
196 (define_function_unit "div" 1 1
197 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23
198 (define_function_unit "div" 1 1
199 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18
201 ;; Superoptimizer sequences
203 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
208 [(set (match_operand:SI 0 "register_operand" "=r")
209 (minus:SI (match_operand:SI 1 "register_operand" "r")
210 (geu:SI (match_operand:SI 2 "register_operand" "r")
211 (match_operand:SI 3 "register_operand" "r"))))]
213 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
215 (plus:SI (match_dup 1)
216 (unspec:SI [(const_int 0)
220 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
225 [(set (match_operand:SI 0 "register_operand" "=r")
226 (minus:SI (match_operand:SI 1 "register_operand" "r")
227 (leu:SI (match_operand:SI 3 "register_operand" "r")
228 (match_operand:SI 2 "register_operand" "r"))))]
230 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
232 (plus:SI (match_dup 1)
233 (unspec:SI [(const_int 0)
237 ;; eq0+: { r = (v0 == 0) + v1; }
242 [(set (match_operand:SI 0 "register_operand" "=r")
243 (minus:SI (match_operand:SI 1 "register_operand" "r")
244 (eq:SI (match_operand:SI 2 "register_operand" "r")
247 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
249 (plus:SI (match_dup 1)
250 (unspec:SI [(const_int 0)
254 ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
259 [(set (match_operand:SI 0 "register_operand" "=r")
260 (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
261 (match_operand:SI 3 "register_operand" "r"))
262 (match_operand:SI 1 "register_operand" "r")))]
264 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
266 (minus:SI (match_dup 1)
267 (unspec:SI [(const_int 0)
271 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
276 [(set (match_operand:SI 0 "register_operand" "=r")
277 (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
278 (match_operand:SI 2 "register_operand" "r"))
279 (match_operand:SI 1 "register_operand" "r")))]
281 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
283 (minus:SI (match_dup 1)
284 (unspec:SI [(const_int 0)
288 ;; ne0-: { r = v1 - (v0 != 0); }
293 [(set (match_operand:SI 0 "register_operand" "=r")
294 (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
296 (match_operand:SI 1 "register_operand" "r")))]
298 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
300 (minus:SI (match_dup 1)
301 (unspec:SI [(const_int 0)
305 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
310 [(set (match_operand:SI 0 "register_operand" "=r")
311 (minus:SI (match_operand:SI 1 "register_operand" "r")
313 (match_operand:SI 2 "register_operand" "r")
317 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
319 (minus:SI (match_dup 1)
320 (unspec:SI [(const_int 0)
324 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
325 ;; (tege@sics.se). They've changed since then, so don't complain to him
326 ;; if they don't work right.
328 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions
329 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
330 ;; special needs to be done here.
332 ;; Optimize possible cases of the set instruction.
335 [(set (match_operand:SI 0 "register_operand" "=r")
336 (ashift:SI (const_int -1)
337 (match_operand:SI 1 "register_operand" "r")))]
340 [(set_attr "type" "bit")])
343 [(set (match_operand:SI 0 "register_operand" "=r")
344 (ior:SI (ashift:SI (const_int -1)
345 (match_operand:SI 1 "register_operand" "r"))
346 (match_operand:SI 2 "register_operand" "r")))]
349 [(set_attr "type" "bit")])
352 [(set (match_operand:SI 0 "register_operand" "=r")
353 (ior:SI (match_operand:SI 1 "register_operand" "r")
354 (ashift:SI (const_int -1)
355 (match_operand:SI 2 "register_operand" "r"))))]
358 [(set_attr "type" "bit")])
360 ;; Optimize possible cases of the mak instruction.
363 [(set (match_operand:SI 0 "register_operand" "=r")
364 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
365 (match_operand:SI 2 "int5_operand" ""))
366 (match_operand:SI 3 "immediate_operand" "n")))]
367 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
370 operands[4] = gen_rtx (CONST_INT, SImode,
371 exact_log2 (1 + (INTVAL (operands[3])
372 >> INTVAL(operands[2]))));
373 return \"mak %0,%1,%4<%2>\";
375 [(set_attr "type" "bit")])
377 ;; Optimize possible cases of output_and.
380 [(set (match_operand:SI 0 "register_operand" "=r")
381 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
382 (match_operand:SI 2 "int5_operand" "")
383 (match_operand:SI 3 "int5_operand" ""))
384 (match_operand:SI 4 "int5_operand" "")))]
385 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
389 = gen_rtx (CONST_INT, SImode,
390 ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
391 return output_and (operands);
393 [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.
395 ;; Improve logical operations on compare words
397 ;; We define all logical operations on CCmode values to preserve the pairwise
398 ;; relationship of the compare bits. This allows a future branch prediction
399 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
400 ;; THIS IS CURRENTLY FALSE!
402 ;; Opportunities arise when conditional expressions using && and || are made
403 ;; unconditional. When these are used to branch, the sequence is
404 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create
405 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
406 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
408 ;; When the extracted conditions are the same, the define_split patterns
409 ;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed
410 ;; conditions match, one compare word can be complimented, resulting in
411 ;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.
412 ;; If the conditions don't line up, one can be rotated. To keep the pairwise
413 ;; relationship, it may be necessary to both rotate and compliment. Rotating
414 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
415 ;; we don't do this for ext/ext/{and,or}.
417 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
418 ;; into an alternate form of bb0 and bb1.
421 [(set (match_operand:SI 0 "register_operand" "=r")
423 (match_operator 1 "even_relop"
424 [(match_operand 2 "partial_ccmode_register_operand" "%r")
427 (match_operator 3 "relop"
428 [(match_operand 4 "partial_ccmode_register_operand" "r")
430 (clobber (match_operand:SI 5 "register_operand" "=r"))]
433 (ior:CCEVEN (match_dup 4)
436 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
437 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
438 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
439 ; /* The conditions match. */
440 else if (GET_CODE (operands[1])
441 == reverse_condition (GET_CODE (operands[3])))
442 /* Reverse the condition by complimenting the compare word. */
443 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
446 /* Make the condition pairs line up by rotating the compare word. */
447 int cv1 = condition_value (operands[1]);
448 int cv2 = condition_value (operands[3]);
450 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
451 gen_rtx (CONST_INT, VOIDmode,
452 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
453 /* Reverse the condition if needed. */
454 if ((cv1 & 1) != (cv2 & 1))
455 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
459 [(set (match_operand:SI 0 "register_operand" "=r")
461 (match_operator 1 "odd_relop"
462 [(match_operand 2 "partial_ccmode_register_operand" "%r")
465 (match_operator 3 "odd_relop"
466 [(match_operand 4 "partial_ccmode_register_operand" "r")
468 (clobber (match_operand:SI 5 "register_operand" "=r"))]
471 (and:CCEVEN (match_dup 4)
474 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
475 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
476 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
477 ; /* The conditions match. */
480 /* Make the condition pairs line up by rotating the compare word. */
481 int cv1 = condition_value (operands[1]);
482 int cv2 = condition_value (operands[3]);
484 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
485 gen_rtx (CONST_INT, VOIDmode,
486 (cv2 - cv1) & 0x1f));
490 [(set (match_operand:SI 0 "register_operand" "=r")
492 (match_operator 1 "odd_relop"
493 [(match_operand 2 "partial_ccmode_register_operand" "%r")
496 (match_operator 3 "even_relop"
497 [(match_operand 4 "partial_ccmode_register_operand" "r")
499 (clobber (match_operand:SI 5 "register_operand" "=r"))]
502 (ior:CCEVEN (not:CC (match_dup 2))
505 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
506 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
507 if (GET_CODE (operands[1])
508 == reverse_condition (GET_CODE (operands[3])))
512 /* Make the condition pairs line up by rotating the compare word. */
513 int cv1 = condition_value (operands[1]);
514 int cv2 = condition_value (operands[3]);
516 operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
517 gen_rtx (CONST_INT, VOIDmode,
518 ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
522 [(set (match_operand:SI 0 "register_operand" "=r")
523 (ior:SI (match_operator 1 "even_relop"
524 [(match_operand 2 "partial_ccmode_register_operand" "%r")
526 (match_operator 3 "relop"
527 [(match_operand 4 "partial_ccmode_register_operand" "r")
529 (clobber (match_operand:SI 5 "register_operand" "=r"))]
530 "GET_CODE (operands[1]) == GET_CODE (operands[3])
531 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
533 (ior:CCEVEN (match_dup 4)
536 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
537 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
538 /* Reverse the condition by complimenting the compare word. */
539 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
540 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
543 [(set (match_operand:SI 0 "register_operand" "=r")
544 (ior:SI (match_operator 1 "odd_relop"
545 [(match_operand 2 "partial_ccmode_register_operand" "%r")
547 (match_operator 3 "odd_relop"
548 [(match_operand 4 "partial_ccmode_register_operand" "r")
550 (clobber (match_operand:SI 5 "register_operand" "=r"))]
551 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
553 (and:CCEVEN (match_dup 4)
556 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
557 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
560 [(set (match_operand:SI 0 "register_operand" "=r")
561 (ior:SI (match_operator 1 "odd_relop"
562 [(match_operand 2 "partial_ccmode_register_operand" "%r")
564 (match_operator 3 "even_relop"
565 [(match_operand 4 "partial_ccmode_register_operand" "r")
567 (clobber (match_operand:SI 5 "register_operand" "=r"))]
568 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
570 (ior:CCEVEN (not:CC (match_dup 4))
573 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
574 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
577 [(set (match_operand:SI 0 "register_operand" "=r")
579 (match_operator 1 "even_relop"
580 [(match_operand 2 "partial_ccmode_register_operand" "%r")
583 (match_operator 3 "relop"
584 [(match_operand 4 "partial_ccmode_register_operand" "r")
586 (clobber (match_operand:SI 5 "register_operand" "=r"))]
589 (and:CCEVEN (match_dup 4)
592 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
593 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
594 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
595 ; /* The conditions match. */
596 else if (GET_CODE (operands[1])
597 == reverse_condition (GET_CODE (operands[3])))
598 /* Reverse the condition by complimenting the compare word. */
599 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
602 /* Make the condition pairs line up by rotating the compare word. */
603 int cv1 = condition_value (operands[1]);
604 int cv2 = condition_value (operands[3]);
605 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
606 gen_rtx (CONST_INT, VOIDmode,
607 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
608 /* Reverse the condition if needed. */
609 if ((cv1 & 1) != (cv2 & 1))
610 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
614 [(set (match_operand:SI 0 "register_operand" "=r")
616 (match_operator 1 "odd_relop"
617 [(match_operand 2 "partial_ccmode_register_operand" "%r")
620 (match_operator 3 "odd_relop"
621 [(match_operand 4 "partial_ccmode_register_operand" "r")
623 (clobber (match_operand:SI 5 "register_operand" "=r"))]
626 (ior:CCEVEN (match_dup 4)
629 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
630 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
631 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
632 ; /* The conditions match. */
635 /* Make the condition pairs line up by rotating the compare word. */
636 int cv1 = condition_value (operands[1]);
637 int cv2 = condition_value (operands[3]);
638 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
639 gen_rtx (CONST_INT, VOIDmode,
640 (cv2 - cv1) & 0x1f));
644 [(set (match_operand:SI 0 "register_operand" "=r")
646 (match_operator 1 "odd_relop"
647 [(match_operand 2 "partial_ccmode_register_operand" "%r")
650 (match_operator 3 "even_relop"
651 [(match_operand 4 "partial_ccmode_register_operand" "r")
653 (clobber (match_operand:SI 5 "register_operand" "=r"))]
656 (and:CCEVEN (not:CC (match_dup 2))
659 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
660 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
661 if (GET_CODE (operands[1])
662 == reverse_condition (GET_CODE (operands[3])))
666 /* Make the condition pairs line up by rotating the compare word. */
667 int cv1 = condition_value (operands[1]);
668 int cv2 = condition_value (operands[3]);
669 operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
670 gen_rtx (CONST_INT, VOIDmode,
671 ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
675 [(set (match_operand:SI 0 "register_operand" "=r")
676 (and:SI (match_operator 1 "even_relop"
677 [(match_operand 2 "partial_ccmode_register_operand" "%r")
679 (match_operator 3 "relop"
680 [(match_operand 4 "partial_ccmode_register_operand" "r")
682 (clobber (match_operand:SI 5 "register_operand" "=r"))]
683 "GET_CODE (operands[1]) == GET_CODE (operands[3])
684 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
686 (and:CCEVEN (match_dup 4)
689 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
690 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
691 /* Reverse the condition by complimenting the compare word. */
692 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
693 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
696 [(set (match_operand:SI 0 "register_operand" "=r")
697 (and:SI (match_operator 1 "odd_relop"
698 [(match_operand 2 "partial_ccmode_register_operand" "%r")
700 (match_operator 3 "odd_relop"
701 [(match_operand 4 "partial_ccmode_register_operand" "r")
703 (clobber (match_operand:SI 5 "register_operand" "=r"))]
704 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
706 (ior:CCEVEN (match_dup 4)
709 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
710 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
713 [(set (match_operand:SI 0 "register_operand" "=r")
714 (and:SI (match_operator 1 "odd_relop"
715 [(match_operand 2 "partial_ccmode_register_operand" "%r")
717 (match_operator 3 "even_relop"
718 [(match_operand 4 "partial_ccmode_register_operand" "r")
720 (clobber (match_operand:SI 5 "register_operand" "=r"))]
721 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
723 (and:CCEVEN (not:CC (match_dup 2))
726 (match_op_dup 3 [(match_dup 5) (const_int 0)]))]
727 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
730 ;; Logical operations on compare words.
733 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
734 (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
735 (match_operand 2 "partial_ccmode_register_operand" "r")))]
740 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
741 (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
742 (match_operand 2 "partial_ccmode_register_operand" "r")))]
747 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
748 (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
749 (match_operand 2 "partial_ccmode_register_operand" "r")))]
754 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
755 (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
756 (match_operand 2 "partial_ccmode_register_operand" "r")))]
761 [(set (match_operand:CC 0 "register_operand" "=r")
762 (rotate:CC (match_operand:CC 1 "register_operand" "r")
763 (match_operand:CC 2 "int5_operand" "")))]
766 [(set_attr "type" "bit")])
769 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
770 (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
771 (match_operand:CC 2 "int5_operand" "")))]
774 [(set_attr "type" "bit")])
776 ;; rotate/and[.c] and rotate/ior[.c]
779 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
780 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
781 (match_operand:CC 2 "int5_operand" ""))
782 (match_operand 3 "partial_ccmode_register_operand" "r")))
783 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
786 (rotate:CC (match_dup 1) (match_dup 2)))
788 (ior:CCEVEN (match_dup 4) (match_dup 3)))]
792 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
793 (ior:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
794 (match_operand:CC 2 "int5_operand" ""))
795 (match_operand 3 "partial_ccmode_register_operand" "r")))
796 (clobber (match_scratch:CCEVEN 4 "=r"))]
801 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
802 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
803 (match_operand:CC 2 "int5_operand" "")))
804 (match_operand 3 "partial_ccmode_register_operand" "r")))
805 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
808 (rotate:CC (match_dup 1) (match_dup 2)))
810 (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
814 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
815 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
816 (match_operand:CC 2 "int5_operand" "")))
817 (match_operand 3 "partial_ccmode_register_operand" "r")))
818 (clobber (match_scratch:CCEVEN 4 "=r"))]
823 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
824 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
825 (match_operand:CC 2 "int5_operand" ""))
826 (match_operand 3 "partial_ccmode_register_operand" "r")))
827 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
830 (rotate:CC (match_dup 1) (match_dup 2)))
832 (and:CCEVEN (match_dup 4) (match_dup 3)))]
836 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
837 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
838 (match_operand:CC 2 "int5_operand" ""))
839 (match_operand 3 "partial_ccmode_register_operand" "r")))
840 (clobber (match_scratch:CCEVEN 4 "=r"))]
845 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
846 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
847 (match_operand:CC 2 "int5_operand" "")))
848 (match_operand 3 "partial_ccmode_register_operand" "r")))
849 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
852 (rotate:CC (match_dup 1) (match_dup 2)))
854 (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
858 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
859 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
860 (match_operand:CC 2 "int5_operand" "")))
861 (match_operand 3 "partial_ccmode_register_operand" "r")))
862 (clobber (match_scratch:CCEVEN 4 "=r"))]
867 ;; Recognize bcnd instructions for integer values. This is distinguished
868 ;; from a conditional branch instruction (below) with SImode instead of
874 (match_operator 0 "relop_no_unsigned"
875 [(match_operand:SI 1 "register_operand" "r")
877 (match_operand 2 "pc_or_label_ref" "")
878 (match_operand 3 "pc_or_label_ref" "")))]
880 "bcnd%. %R3%B0,%1,%P2%P3"
881 [(set_attr "type" "branch")])
883 ;; Recognize tests for sign and zero.
888 (match_operator 0 "equality_op"
889 [(match_operand:SI 1 "register_operand" "r")
890 (const_int -2147483648)])
891 (match_operand 2 "pc_or_label_ref" "")
892 (match_operand 3 "pc_or_label_ref" "")))]
894 "bcnd%. %R3%E0,%1,%P2%P3"
895 [(set_attr "type" "branch")])
900 (match_operator 0 "equality_op"
902 (match_operand:SI 1 "register_operand" "r")
906 (match_operand 2 "pc_or_label_ref" "")
907 (match_operand 3 "pc_or_label_ref" "")))]
909 "bcnd%. %R3%D0,%1,%P2%P3"
910 [(set_attr "type" "branch")])
912 ;; Recognize bcnd instructions for double integer values
917 (match_operator 0 "relop_no_unsigned"
919 (match_operand:SI 1 "register_operand" "r"))
921 (match_operand 2 "pc_or_label_ref" "")
922 (match_operand 3 "pc_or_label_ref" "")))]
924 "bcnd%. %R3%B0,%1,%P2%P3"
925 [(set_attr "type" "branch")])
930 (match_operator 0 "equality_op"
932 (match_operand:SI 1 "register_operand" "r"))
934 (match_operand 2 "pc_or_label_ref" "")
935 (match_operand 3 "pc_or_label_ref" "")))]
937 "bcnd%. %R3%B0,%1,%P2%P3"
938 [(set_attr "type" "branch")])
940 ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs
946 ; (match_operator 0 "relop_no_unsigned"
947 ; [(match_operand:DI 1 "register_operand" "r")
949 ; (match_operand 2 "pc_or_label_ref" "")
950 ; (match_operand 3 "pc_or_label_ref" "")))]
954 ; switch (GET_CODE (operands[0]))
958 ; /* I'm not sure if it's safe to use .n here. */
959 ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
962 ; return \"bcnd%. %R3%B0,%1,%P2%P3\";
965 ; rtx op2 = operands[2];
966 ; operands[2] = operands[3];
970 ; if (GET_CODE (operands[3]) == LABEL_REF)
973 ; operands[2] = gen_label_rtx ();
974 ; label_num = XINT (operands[2], 3);
976 ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
977 ; output_label (label_num);
981 ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
985 ;; Recognize bcnd instructions for single precision float values
986 ;; Exclude relational operations as they must signal NaNs.
988 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
993 (match_operator 0 "equality_op"
995 (match_operand:SF 1 "register_operand" "r"))
997 (match_operand 2 "pc_or_label_ref" "")
998 (match_operand 3 "pc_or_label_ref" "")))]
1000 "bcnd%. %R3%D0,%1,%P2%P3"
1001 [(set_attr "type" "branch")])
1006 (match_operator 0 "equality_op"
1007 [(match_operand:SF 1 "register_operand" "r")
1009 (match_operand 2 "pc_or_label_ref" "")
1010 (match_operand 3 "pc_or_label_ref" "")))]
1012 "bcnd%. %R3%D0,%1,%P2%P3"
1013 [(set_attr "type" "branch")])
1015 ;; Recognize bcnd instructions for double precision float values
1016 ;; Exclude relational operations as they must signal NaNs.
1021 (match_operator 0 "equality_op"
1022 [(match_operand:DF 1 "register_operand" "r")
1024 (match_operand 2 "pc_or_label_ref" "")
1025 (match_operand 3 "pc_or_label_ref" "")))]
1031 if (GET_CODE (operands[0]) == NE)
1033 rtx op2 = operands[2];
1034 operands[2] = operands[3];
1037 if (GET_CODE (operands[3]) == LABEL_REF)
1038 return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
1040 operands[3] = gen_label_rtx ();
1041 label_num = XINT (operands[3], 3);
1042 output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
1043 output_label (label_num);
1046 [(set_attr "type" "weird")
1047 (set_attr "length" "3")])
1049 ;; Recognize bb0 and bb1 instructions. These use two unusual template
1050 ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF
1051 ;; otherwise it outputs a 0. It then may print ".n" if the delay slot
1052 ;; is used. %Px does noting if `x' is PC and outputs the operand if `x'
1058 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1060 (match_operand:SI 1 "int5_operand" ""))
1062 (match_operand 2 "pc_or_label_ref" "")
1063 (match_operand 3 "pc_or_label_ref" "")))]
1065 "bb%L2 (31-%1),%0,%P2%P3"
1066 [(set_attr "type" "branch")])
1071 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1073 (match_operand:SI 1 "int5_operand" ""))
1075 (match_operand 2 "pc_or_label_ref" "")
1076 (match_operand 3 "pc_or_label_ref" "")))]
1078 "bb%L3 (31-%1),%0,%P2%P3"
1079 [(set_attr "type" "branch")])
1084 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1086 (match_operand:SI 1 "int5_operand" ""))
1088 (match_operand 2 "pc_or_label_ref" "")
1089 (match_operand 3 "pc_or_label_ref" "")))]
1091 "bb%L2 (31-%1),%0,%P2%P3"
1092 [(set_attr "type" "branch")])
1097 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1099 (match_operand:SI 1 "int5_operand" ""))
1101 (match_operand 2 "pc_or_label_ref" "")
1102 (match_operand 3 "pc_or_label_ref" "")))]
1104 "bb%L3 (31-%1),%0,%P2%P3"
1105 [(set_attr "type" "branch")])
1110 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1111 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1113 (match_operand 2 "pc_or_label_ref" "")
1114 (match_operand 3 "pc_or_label_ref" "")))]
1115 "(GET_CODE (operands[0]) == CONST_INT)
1116 != (GET_CODE (operands[1]) == CONST_INT)"
1117 "bb%L3 %p1,%0,%P2%P3"
1118 [(set_attr "type" "branch")])
1123 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1124 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1126 (match_operand 2 "pc_or_label_ref" "")
1127 (match_operand 3 "pc_or_label_ref" "")))]
1128 "(GET_CODE (operands[0]) == CONST_INT)
1129 != (GET_CODE (operands[1]) == CONST_INT)"
1130 "bb%L2 %p1,%0,%P2%P3"
1131 [(set_attr "type" "branch")])
1133 ;; The comparison operations store the comparison into a register and
1134 ;; record that register. The following Bxx or Sxx insn uses that
1135 ;; register as an input. To facilitate use of bcnd instead of cmp/bb1,
1136 ;; cmpsi records it's operands and produces no code when any operand
1137 ;; is constant. In this case, the Bxx insns use gen_bcnd and the
1138 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
1140 ;; This could also be done for SFmode and DFmode having only beq and bne
1141 ;; use gen_bcnd. The others must signal NaNs. It seems though that zero
1142 ;; has already been copied into a register.
1144 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1145 ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can
1146 ;; use bcnd only if an operand is zero.
1148 ;; It is necessary to distinguish a register holding condition codes.
1149 ;; This is done by context.
1151 (define_expand "test"
1153 (compare:CC (match_operand 0 "" "")
1154 (match_operand 1 "" "")))]
1158 if (m88k_compare_reg)
1161 if (GET_CODE (operands[0]) == CONST_INT
1162 && ! SMALL_INT (operands[0]))
1163 operands[0] = force_reg (SImode, operands[0]);
1165 if (GET_CODE (operands[1]) == CONST_INT
1166 && ! SMALL_INT (operands[1]))
1167 operands[1] = force_reg (SImode, operands[1]);
1169 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1172 ; @@ The docs say don't do this. It's probably a nop since the insn looks
1173 ; identical to cmpsi against zero. Is there an advantage to providing
1174 ; this, perhaps with a different form?
1176 ;(define_expand "tstsi"
1177 ; [(set (match_dup 1)
1178 ; (compare:CC (match_operand:SI 0 "register_operand" "")
1183 ; m88k_compare_reg = 0;
1184 ; m88k_compare_op0 = operands[0];
1185 ; m88k_compare_op1 = const0_rtx;
1189 (define_expand "cmpsi"
1191 (compare:CC (match_operand:SI 0 "register_operand" "")
1192 (match_operand:SI 1 "arith32_operand" "")))]
1196 if (GET_CODE (operands[0]) == CONST_INT
1197 || GET_CODE (operands[1]) == CONST_INT)
1199 m88k_compare_reg = 0;
1200 m88k_compare_op0 = operands[0];
1201 m88k_compare_op1 = operands[1];
1204 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1207 (define_expand "cmpsf"
1209 (compare:CC (match_operand:SF 0 "register_operand" "")
1210 (match_operand:SF 1 "register_operand" "")))]
1212 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1214 (define_expand "cmpdf"
1216 (compare:CC (match_operand:DF 0 "general_operand" "")
1217 (match_operand:DF 1 "general_operand" "")))]
1221 operands[0] = legitimize_operand (operands[0], DFmode);
1222 operands[1] = legitimize_operand (operands[1], DFmode);
1223 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1226 ; @@ Get back to this later on.
1228 ;(define_insn "cmpdi"
1230 ; (compare:CC (match_operand:DI 0 "register_operand" "r")
1231 ; (match_operand:DI 1 "register_operand" "r")))]
1235 ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1236 ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */
1238 ; cc_status.mdep &= ~ MDEP_LS_MASK;
1240 ; operands[2] = gen_label_rtx ();
1241 ; /* Remember, %! is the condition code register and %@ is the
1242 ; literal synthesis register. */
1244 ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1247 ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1248 ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1249 ; output_label (XINT (operands[2], 3));
1253 ;; The actual compare instructions.
1256 [(set (match_operand:CC 0 "register_operand" "=r")
1257 (compare:CC (match_operand:SI 1 "register_operand" "rO")
1258 (match_operand:SI 2 "arith_operand" "rI")))]
1263 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1264 (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1265 (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1271 fcmp.sss %0,%1,%#x0"
1272 [(set_attr "type" "spcmp")])
1275 [(set (match_operand:CC 0 "register_operand" "=r,r")
1276 (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1278 (match_operand:SF 2 "register_operand" "r,x"))))]
1281 [(set_attr "type" "dpcmp")])
1284 [(set (match_operand:CC 0 "register_operand" "=r,r")
1285 (compare:CC (float_extend:DF
1286 (match_operand:SF 1 "register_operand" "r,x"))
1287 (match_operand:DF 2 "register_operand" "r,x")))]
1290 [(set_attr "type" "dpcmp")])
1293 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1294 (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1295 (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1301 fcmp.sds %0,%1,%#x0"
1302 [(set_attr "type" "dpcmp")])
1304 ;; Store condition code insns. The compare insns set a register
1305 ;; rather than cc0 and record that register for use here. See above
1306 ;; for the special treatment of cmpsi with a constant operand.
1308 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1310 (define_expand "seq"
1311 [(set (match_operand:SI 0 "register_operand" "")
1314 "operands[1] = emit_test (EQ, SImode);")
1316 (define_expand "sne"
1317 [(set (match_operand:SI 0 "register_operand" "")
1320 "operands[1] = emit_test (NE, SImode);")
1322 (define_expand "sgt"
1323 [(set (match_operand:SI 0 "register_operand" "")
1326 "operands[1] = emit_test (GT, SImode);")
1328 (define_expand "sgtu"
1329 [(set (match_operand:SI 0 "register_operand" "")
1332 "operands[1] = emit_test (GTU, SImode);")
1334 (define_expand "slt"
1335 [(set (match_operand:SI 0 "register_operand" "")
1338 "operands[1] = emit_test (LT, SImode);")
1340 (define_expand "sltu"
1341 [(set (match_operand:SI 0 "register_operand" "")
1344 "operands[1] = emit_test (LTU, SImode);")
1346 (define_expand "sge"
1347 [(set (match_operand:SI 0 "register_operand" "")
1350 "operands[1] = emit_test (GE, SImode);")
1352 (define_expand "sgeu"
1353 [(set (match_operand:SI 0 "register_operand" "")
1356 "operands[1] = emit_test (GEU, SImode);")
1358 (define_expand "sle"
1359 [(set (match_operand:SI 0 "register_operand" "")
1362 "operands[1] = emit_test (LE, SImode);")
1364 (define_expand "sleu"
1365 [(set (match_operand:SI 0 "register_operand" "")
1368 "operands[1] = emit_test (LEU, SImode);")
1370 ;; The actual set condition code instruction.
1373 [(set (match_operand:SI 0 "register_operand" "=r")
1374 (match_operator:SI 1 "relop"
1375 [(match_operand:CC 2 "register_operand" "r")
1379 [(set_attr "type" "bit")])
1382 [(set (match_operand:SI 0 "register_operand" "=r")
1383 (match_operator:SI 1 "even_relop"
1384 [(match_operand:CCEVEN 2 "register_operand" "r")
1388 [(set_attr "type" "bit")])
1391 [(set (match_operand:SI 0 "register_operand" "=r")
1392 (not:SI (match_operator:SI 1 "odd_relop"
1393 [(match_operand:CCEVEN 2 "register_operand" "r")
1396 "ext %0,%2,1<%!%C1>"
1397 [(set_attr "type" "bit")])
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_operand:SI 3 "register_operand" "=r"))]
1406 [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1407 (set (match_dup 0) (not:SI (match_dup 3)))]
1411 [(set (match_operand:SI 0 "register_operand" "=r")
1412 (match_operator:SI 1 "odd_relop"
1413 [(match_operand:CCEVEN 2 "register_operand" "r")
1415 (clobber (match_scratch:SI 3 "=r"))]
1420 [(set (match_operand:SI 0 "register_operand" "=r")
1422 (match_operator:SI 1 "relop"
1423 [(match_operand:CC 2 "register_operand" "r")
1427 [(set_attr "type" "bit")])
1430 [(set (match_operand:SI 0 "register_operand" "=r")
1432 (match_operator:SI 1 "even_relop"
1433 [(match_operand:CCEVEN 2 "register_operand" "r")
1437 [(set_attr "type" "bit")])
1440 [(set (match_operand:SI 0 "register_operand" "=r")
1442 (not:SI (match_operator:SI 1 "odd_relop"
1443 [(match_operand:CCEVEN 2 "register_operand" "r")
1446 "extu %0,%2,1<%!%C1>"
1447 [(set_attr "type" "bit")])
1450 [(set (match_operand:SI 0 "register_operand" "=r")
1451 (neg:SI (match_operator:SI 1 "odd_relop"
1452 [(match_operand:CCEVEN 2 "register_operand" "r")
1454 (clobber (match_operand:SI 3 "register_operand" "=r"))]
1456 [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1458 (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1463 [(set (match_operand:SI 0 "register_operand" "=r")
1464 (neg:SI (match_operator:SI 1 "odd_relop"
1465 [(match_operand:CCEVEN 2 "register_operand" "r")
1467 (clobber (match_scratch:SI 3 "=r"))]
1474 ;; Conditional branch insns. The compare insns set a register
1475 ;; rather than cc0 and record that register for use here. See above
1476 ;; for the special case of cmpsi with a constant operand.
1478 (define_expand "bcnd"
1480 (if_then_else (match_operand 0 "" "")
1481 (label_ref (match_operand 1 "" ""))
1484 "if (m88k_compare_reg) abort ();")
1486 (define_expand "bxx"
1488 (if_then_else (match_operand 0 "" "")
1489 (label_ref (match_operand 1 "" ""))
1492 "if (m88k_compare_reg == 0) abort ();")
1494 (define_expand "beq"
1496 (if_then_else (eq (match_dup 1) (const_int 0))
1497 (label_ref (match_operand 0 "" ""))
1500 "if (m88k_compare_reg == 0)
1502 emit_bcnd (EQ, operands[0]);
1505 operands[1] = m88k_compare_reg;")
1507 (define_expand "bne"
1509 (if_then_else (ne (match_dup 1) (const_int 0))
1510 (label_ref (match_operand 0 "" ""))
1513 "if (m88k_compare_reg == 0)
1515 emit_bcnd (NE, operands[0]);
1518 operands[1] = m88k_compare_reg;")
1520 (define_expand "bgt"
1522 (if_then_else (gt (match_dup 1) (const_int 0))
1523 (label_ref (match_operand 0 "" ""))
1526 "if (m88k_compare_reg == 0)
1528 emit_bcnd (GT, operands[0]);
1531 operands[1] = m88k_compare_reg;")
1533 (define_expand "bgtu"
1535 (if_then_else (gtu (match_dup 1) (const_int 0))
1536 (label_ref (match_operand 0 "" ""))
1539 "if (m88k_compare_reg == 0)
1541 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1544 operands[1] = m88k_compare_reg;")
1546 (define_expand "blt"
1548 (if_then_else (lt (match_dup 1) (const_int 0))
1549 (label_ref (match_operand 0 "" ""))
1552 "if (m88k_compare_reg == 0)
1554 emit_bcnd (LT, operands[0]);
1557 operands[1] = m88k_compare_reg;")
1559 (define_expand "bltu"
1561 (if_then_else (ltu (match_dup 1) (const_int 0))
1562 (label_ref (match_operand 0 "" ""))
1565 "if (m88k_compare_reg == 0)
1567 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1570 operands[1] = m88k_compare_reg;")
1572 (define_expand "bge"
1574 (if_then_else (ge (match_dup 1) (const_int 0))
1575 (label_ref (match_operand 0 "" ""))
1578 "if (m88k_compare_reg == 0)
1580 emit_bcnd (GE, operands[0]);
1583 operands[1] = m88k_compare_reg;")
1585 (define_expand "bgeu"
1587 (if_then_else (geu (match_dup 1) (const_int 0))
1588 (label_ref (match_operand 0 "" ""))
1591 "if (m88k_compare_reg == 0)
1593 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1596 operands[1] = m88k_compare_reg;")
1598 (define_expand "ble"
1600 (if_then_else (le (match_dup 1) (const_int 0))
1601 (label_ref (match_operand 0 "" ""))
1604 "if (m88k_compare_reg == 0)
1606 emit_bcnd (LE, operands[0]);
1609 operands[1] = m88k_compare_reg;")
1611 (define_expand "bleu"
1613 (if_then_else (leu (match_dup 1) (const_int 0))
1614 (label_ref (match_operand 0 "" ""))
1617 "if (m88k_compare_reg == 0)
1619 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1622 operands[1] = m88k_compare_reg;")
1624 ;; The actual conditional branch instruction (both directions). This
1625 ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code
1626 ;; for the immediately following condition and reverses the condition iff
1627 ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs
1628 ;; the operand if `x' is a LABEL_REF.
1631 [(set (pc) (if_then_else
1632 (match_operator 0 "relop"
1633 [(match_operand:CC 1 "register_operand" "r")
1635 (match_operand 2 "pc_or_label_ref" "")
1636 (match_operand 3 "pc_or_label_ref" "")))]
1640 if (mostly_false_jump (insn, operands[0]))
1641 return \"bb0%. %R2%C0,%1,%P2%P3\";
1643 return \"bb1%. %R3%C0,%1,%P2%P3\";
1645 [(set_attr "type" "branch")])
1648 ;; Here branch prediction is sacrificed. To get it back, you need
1649 ;; - CCODD (CC mode where the ODD bits are valid)
1650 ;; - several define_split that can apply De Morgan's Law.
1651 ;; - transformations between CCEVEN and CCODD modes.
1655 [(set (pc) (if_then_else
1656 (match_operator 0 "even_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%L2%. %C0,%1,%P2%P3"
1663 [(set_attr "type" "branch")])
1666 [(set (pc) (if_then_else
1667 (match_operator 0 "odd_relop"
1668 [(match_operand:CCEVEN 1 "register_operand" "r")
1670 (match_operand 2 "pc_or_label_ref" "")
1671 (match_operand 3 "pc_or_label_ref" "")))]
1673 "bb%L3%. %!%C0,%1,%P2%P3"
1674 [(set_attr "type" "branch")])
1676 ;; Branch conditional on scc values. These arise from manipulations on
1677 ;; compare words above.
1678 ;; Are these really used ?
1683 (ne (match_operator 0 "relop"
1684 [(match_operand:CC 1 "register_operand" "r")
1687 (match_operand 2 "pc_or_label_ref" "")
1688 (match_operand 3 "pc_or_label_ref" "")))]
1690 "bb%L2 %C0,%1,%P2%P3"
1691 [(set_attr "type" "branch")])
1696 (ne (match_operator 0 "even_relop"
1697 [(match_operand:CCEVEN 1 "register_operand" "r")
1700 (match_operand 2 "pc_or_label_ref" "")
1701 (match_operand 3 "pc_or_label_ref" "")))]
1703 "bb%L2 %C0,%1,%P2%P3"
1704 [(set_attr "type" "branch")])
1709 (ne (match_operator 0 "odd_relop"
1710 [(match_operand:CCEVEN 1 "register_operand" "r")
1713 (match_operand 2 "pc_or_label_ref" "")
1714 (match_operand 3 "pc_or_label_ref" "")))]
1716 "bb%L3 %!%C0,%1,%P2%P3"
1717 [(set_attr "type" "branch")])
1722 (eq (match_operator 0 "relop"
1723 [(match_operand:CC 1 "register_operand" "r")
1726 (match_operand 2 "pc_or_label_ref" "")
1727 (match_operand 3 "pc_or_label_ref" "")))]
1729 "bb%L3 %C0,%1,%P2%P3"
1730 [(set_attr "type" "branch")])
1735 (eq (match_operator 0 "even_relop"
1736 [(match_operand:CCEVEN 1 "register_operand" "r")
1739 (match_operand 2 "pc_or_label_ref" "")
1740 (match_operand 3 "pc_or_label_ref" "")))]
1742 "bb%L3 %C0,%1,%P2%P3"
1743 [(set_attr "type" "branch")])
1748 (eq (match_operator 0 "odd_relop"
1749 [(match_operand:CCEVEN 1 "register_operand" "r")
1752 (match_operand 2 "pc_or_label_ref" "")
1753 (match_operand 3 "pc_or_label_ref" "")))]
1755 "bb%L2 %!%C0,%1,%P2%P3"
1756 [(set_attr "type" "branch")])
1758 (define_insn "locate1"
1759 [(set (match_operand:SI 0 "register_operand" "=r")
1760 (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1762 "or.u %0,%#r0,%#hi16(%1#abdiff)")
1764 (define_insn "locate2"
1765 [(parallel [(set (reg:SI 1) (pc))
1766 (set (match_operand:SI 0 "register_operand" "=r")
1767 (lo_sum:SI (match_dup 0)
1769 [(label_ref (match_operand 1 "" ""))] 0)))])]
1771 "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1772 [(set_attr "length" "2")])
1774 ;; SImode move instructions
1776 (define_expand "movsi"
1777 [(set (match_operand:SI 0 "general_operand" "")
1778 (match_operand:SI 1 "general_operand" ""))]
1782 if (emit_move_sequence (operands, SImode, 0))
1786 (define_expand "reload_insi"
1787 [(set (match_operand:SI 0 "register_operand" "=r")
1788 (match_operand:SI 1 "general_operand" ""))
1789 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1793 if (emit_move_sequence (operands, SImode, operands[2]))
1796 /* We don't want the clobber emitted, so handle this ourselves. */
1797 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1802 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1803 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1804 "(register_operand (operands[0], SImode)
1805 || register_operand (operands[1], SImode)
1806 || operands[1] == const0_rtx)"
1818 [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1821 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1822 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1829 or.u %0,%#r0,%X1\;or %0,%0,%x1"
1830 [(set_attr "type" "arith,arith,arith,bit,marith")])
1832 ;; @@ Why the constraint "in"? Doesn't `i' include `n'?
1834 [(set (match_operand:SI 0 "register_operand" "=r")
1835 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1836 (match_operand:SI 2 "immediate_operand" "in")))]
1838 "or %0,%1,%#lo16(%g2)")
1840 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1841 ;; confuse them with real addresses.
1843 [(set (match_operand:SI 0 "register_operand" "=r")
1844 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1845 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1847 "or %0,%1,%#lo16(%g2)"
1848 ;; Need to set length for this arith insn because operand2
1849 ;; is not an "arith_operand".
1850 [(set_attr "length" "1")])
1853 [(set (match_operand:SI 0 "register_operand" "=r")
1854 (high:SI (match_operand 1 "" "")))]
1856 "or.u %0,%#r0,%#hi16(%g1)")
1858 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1859 ;; confuse them with real addresses.
1861 [(set (match_operand:SI 0 "register_operand" "=r")
1862 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1864 "or.u %0,%#r0,%#hi16(%g1)"
1865 ;; Need to set length for this arith insn because operand2
1866 ;; is not an arith_operand.
1867 [(set_attr "length" "1")])
1869 ;; HImode move instructions
1871 (define_expand "movhi"
1872 [(set (match_operand:HI 0 "general_operand" "")
1873 (match_operand:HI 1 "general_operand" ""))]
1877 if (emit_move_sequence (operands, HImode, 0))
1882 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1883 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1884 "(register_operand (operands[0], HImode)
1885 || register_operand (operands[1], HImode)
1886 || operands[1] == const0_rtx)"
1892 [(set_attr "type" "arith,load,store,arith")])
1895 [(set (match_operand:HI 0 "register_operand" "=r")
1896 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1897 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1899 "or %0,%1,%#lo16(%2)")
1901 ;; QImode move instructions
1903 (define_expand "movqi"
1904 [(set (match_operand:QI 0 "general_operand" "")
1905 (match_operand:QI 1 "general_operand" ""))]
1909 if (emit_move_sequence (operands, QImode, 0))
1914 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1915 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1916 "(register_operand (operands[0], QImode)
1917 || register_operand (operands[1], QImode)
1918 || operands[1] == const0_rtx)"
1924 [(set_attr "type" "arith,load,store,arith")])
1927 [(set (match_operand:QI 0 "register_operand" "=r")
1928 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1929 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1931 "or %0,%1,%#lo16(%2)")
1933 ;; DImode move instructions
1935 (define_expand "movdi"
1936 [(set (match_operand:DI 0 "general_operand" "")
1937 (match_operand:DI 1 "general_operand" ""))]
1941 if (emit_move_sequence (operands, DImode, 0))
1946 [(set (match_operand:DI 0 "register_operand" "=r,x")
1950 or %0,%#r0,0\;or %d0,%#r0,0
1952 [(set_attr "type" "marith,mov")])
1955 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1956 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1959 or %0,%#r0,%1\;or %d0,%#r0,%d1
1967 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1970 [(set (match_operand:DI 0 "register_operand" "=r")
1971 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1974 "or %0,%1,%#lo16(%2)")
1977 [(set (match_operand:DI 0 "register_operand" "=r")
1978 (match_operand:DI 1 "immediate_operand" "n"))]
1980 "* return output_load_const_dimode (operands);"
1981 [(set_attr "type" "marith")
1982 (set_attr "length" "4")]) ; length is 2, 3 or 4.
1984 ;; DFmode move instructions
1986 (define_expand "movdf"
1987 [(set (match_operand:DF 0 "general_operand" "")
1988 (match_operand:DF 1 "general_operand" ""))]
1992 if (emit_move_sequence (operands, DFmode, 0))
1997 [(set (match_operand:DF 0 "register_operand" "=r")
1998 (match_operand:DF 1 "register_operand" "r"))]
2000 && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
2001 && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
2002 [(set (match_dup 2) (match_dup 3))
2003 (set (match_dup 4) (match_dup 5))]
2005 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2006 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2007 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2008 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
2010 ;; @@ This pattern is incomplete and doesn't appear necessary.
2012 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2013 ;; to be reloaded by putting the constant into memory.
2014 ;; It must come before the more general movdf pattern.
2017 ; [(set (match_operand:DF 0 "general_operand" "=r,o")
2018 ; (match_operand:DF 1 "" "G,G"))]
2019 ; "GET_CODE (operands[1]) == CONST_DOUBLE"
2022 ; switch (which_alternative)
2025 ; return \"or %0,%#r0,0\;or %d0,%#r0,0\";
2027 ; operands[1] = adj_offsettable_operand (operands[0], 4);
2028 ; return \"%v0st\\t %#r0,%0\;st %#r0,%1\";
2033 [(set (match_operand:DF 0 "register_operand" "=r,x")
2037 or %0,%#r0,0\;or %d0,%#r0,0
2039 [(set_attr "type" "marith,mov")])
2042 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2043 (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2046 or %0,%#r0,%1\;or %d0,%#r0,%d1
2054 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2057 [(set (match_operand:DF 0 "register_operand" "=r")
2058 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2059 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2061 "or %0,%1,%#lo16(%2)")
2064 [(set (match_operand:DF 0 "register_operand" "=r")
2065 (match_operand:DF 1 "immediate_operand" "F"))]
2067 "* return output_load_const_double (operands);"
2068 [(set_attr "type" "marith")
2069 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2071 ;; SFmode move instructions
2073 (define_expand "movsf"
2074 [(set (match_operand:SF 0 "general_operand" "")
2075 (match_operand:SF 1 "general_operand" ""))]
2079 if (emit_move_sequence (operands, SFmode, 0))
2083 ;; @@ What happens to fconst0_rtx?
2085 [(set (match_operand:SF 0 "register_operand" "=r,x")
2091 [(set_attr "type" "arith,mov")])
2094 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2095 (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2106 [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2109 [(set (match_operand:SF 0 "register_operand" "=r")
2110 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2111 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2113 "or %0,%1,%#lo16(%2)")
2116 [(set (match_operand:SF 0 "register_operand" "=r")
2117 (match_operand:SF 1 "immediate_operand" "F"))]
2118 "operands[1] != const0_rtx"
2119 "* return output_load_const_float (operands);"
2120 [(set_attr "type" "marith")]) ; length is 1 or 2.
2122 ;; String/block move insn. See m88k.c for details.
2124 (define_expand "movstrsi"
2125 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2126 (mem:BLK (match_operand:BLK 1 "" "")))
2127 (use (match_operand:SI 2 "arith32_operand" ""))
2128 (use (match_operand:SI 3 "immediate_operand" ""))])]
2132 rtx dest_mem = operands[0];
2133 rtx src_mem = operands[1];
2134 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2135 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2136 expand_block_move (dest_mem, src_mem, operands);
2141 [(set (match_operand:QI 0 "register_operand" "=r")
2142 (match_operand:BLK 1 "memory_operand" "m"))]
2145 [(set_attr "type" "load")])
2148 [(set (match_operand:HI 0 "register_operand" "=r")
2149 (match_operand:BLK 1 "memory_operand" "m"))]
2152 [(set_attr "type" "load")])
2155 [(set (match_operand:SI 0 "register_operand" "=r")
2156 (match_operand:BLK 1 "memory_operand" "m"))]
2159 [(set_attr "type" "load")])
2162 [(set (match_operand:DI 0 "register_operand" "=r")
2163 (match_operand:BLK 1 "memory_operand" "m"))]
2166 [(set_attr "type" "loadd")])
2169 [(set (match_operand:BLK 0 "memory_operand" "=m")
2170 (match_operand:QI 1 "register_operand" "r"))]
2173 [(set_attr "type" "store")])
2176 [(set (match_operand:BLK 0 "memory_operand" "=m")
2177 (match_operand:HI 1 "register_operand" "r"))]
2180 [(set_attr "type" "store")])
2183 [(set (match_operand:BLK 0 "memory_operand" "=m")
2184 (match_operand:SI 1 "register_operand" "r"))]
2187 [(set_attr "type" "store")])
2190 [(set (match_operand:BLK 0 "memory_operand" "=m")
2191 (match_operand:DI 1 "register_operand" "r"))]
2194 [(set_attr "type" "store")])
2196 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2197 ;; operand 0 is the function name
2198 ;; operand 1 is the destination pointer
2199 ;; operand 2 is the source pointer
2200 ;; operand 3 is the offset for the source and destination pointers
2201 ;; operand 4 is the first value to be loaded
2202 ;; operand 5 is the register to hold the value (r4 or r5)
2204 (define_expand "call_block_move"
2205 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2206 (match_operand:SI 3 "immediate_operand" "")))
2207 (set (match_operand 5 "register_operand" "")
2208 (match_operand 4 "memory_operand" ""))
2209 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2214 (parallel [(set (reg:DI 2)
2215 (call (mem:SI (match_operand 0 "" ""))
2217 (clobber (reg:SI 1))])]
2221 ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2222 ;; operands 0-5 as in the non-looping interface
2223 ;; operand 6 is the loop count
2225 (define_expand "call_movstrsi_loop"
2226 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2227 (match_operand:SI 3 "immediate_operand" "")))
2228 (set (match_operand:SI 5 "register_operand" "")
2229 (match_operand 4 "memory_operand" ""))
2230 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2232 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2237 (parallel [(set (reg:DI 2)
2238 (call (mem:SI (match_operand 0 "" ""))
2240 (clobber (reg:SI 1))])]
2244 ;;- zero extension instructions
2246 (define_expand "zero_extendhisi2"
2247 [(set (match_operand:SI 0 "register_operand" "")
2248 (zero_extend:SI (match_operand:HI 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:SI 0 "register_operand" "=r,r,r")
2260 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2261 "GET_CODE (operands[1]) != CONST_INT"
2266 [(set_attr "type" "arith,arith,load")])
2268 (define_expand "zero_extendqihi2"
2269 [(set (match_operand:HI 0 "register_operand" "")
2270 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2274 if (GET_CODE (operands[1]) == MEM
2275 && symbolic_address_p (XEXP (operands[1], 0)))
2277 = legitimize_address (flag_pic, operands[1], 0, 0);
2281 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2282 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2283 "GET_CODE (operands[1]) != CONST_INT"
2288 [(set_attr "type" "arith,arith,load")])
2290 (define_expand "zero_extendqisi2"
2291 [(set (match_operand:SI 0 "register_operand" "")
2292 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2296 if (GET_CODE (operands[1]) == MEM
2297 && symbolic_address_p (XEXP (operands[1], 0)))
2300 = legitimize_address (flag_pic, operands[1], 0, 0);
2301 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2302 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
2308 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2309 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2310 "GET_CODE (operands[1]) != CONST_INT"
2315 [(set_attr "type" "arith,arith,load")])
2317 ;;- sign extension instructions
2319 (define_expand "extendsidi2"
2320 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
2321 (match_operand:SI 1 "general_operand" "g"))
2322 (set (subreg:SI (match_dup 0) 0)
2323 (ashiftrt:SI (subreg:SI (match_dup 0) 1)
2328 (define_expand "extendhisi2"
2329 [(set (match_operand:SI 0 "register_operand" "")
2330 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2334 if (GET_CODE (operands[1]) == MEM
2335 && symbolic_address_p (XEXP (operands[1], 0)))
2337 = legitimize_address (flag_pic, operands[1], 0, 0);
2341 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2342 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2343 "GET_CODE (operands[1]) != CONST_INT"
2349 [(set_attr "type" "bit,arith,arith,load")])
2351 (define_expand "extendqihi2"
2352 [(set (match_operand:HI 0 "register_operand" "")
2353 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2357 if (GET_CODE (operands[1]) == MEM
2358 && symbolic_address_p (XEXP (operands[1], 0)))
2360 = legitimize_address (flag_pic, operands[1], 0, 0);
2364 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2365 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2366 "GET_CODE (operands[1]) != CONST_INT"
2372 [(set_attr "type" "bit,arith,arith,load")])
2374 (define_expand "extendqisi2"
2375 [(set (match_operand:SI 0 "register_operand" "")
2376 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2380 if (GET_CODE (operands[1]) == MEM
2381 && symbolic_address_p (XEXP (operands[1], 0)))
2383 = legitimize_address (flag_pic, operands[1], 0, 0);
2387 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2388 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2389 "GET_CODE (operands[1]) != CONST_INT"
2395 [(set_attr "type" "bit,arith,arith,load")])
2397 ;; Conversions between float and double.
2399 ;; The fadd instruction does not conform to IEEE 754 when used to
2400 ;; convert between float and double. In particular, the sign of -0 is
2401 ;; not preserved. Interestingly, fsub does conform.
2403 (define_expand "extendsfdf2"
2404 [(set (match_operand:DF 0 "register_operand" "=r")
2405 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2410 [(set (match_operand:DF 0 "register_operand" "=r")
2411 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2413 "fsub.dss %0,%1,%#r0"
2414 [(set_attr "type" "spadd")])
2417 [(set (match_operand:DF 0 "register_operand" "=r,x")
2418 (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2421 [(set_attr "type" "spadd")])
2423 (define_expand "truncdfsf2"
2424 [(set (match_operand:SF 0 "register_operand" "=r")
2425 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2430 [(set (match_operand:SF 0 "register_operand" "=r")
2431 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2433 "fsub.sds %0,%1,%#r0"
2434 [(set_attr "type" "dpadd")])
2437 [(set (match_operand:SF 0 "register_operand" "=r,x")
2438 (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2441 [(set_attr "type" "dpadd")])
2443 ;; Conversions between floating point and integer
2445 (define_insn "floatsidf2"
2446 [(set (match_operand:DF 0 "register_operand" "=r,x")
2447 (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2450 [(set_attr "type" "spadd,dpadd")])
2452 (define_insn "floatsisf2"
2453 [(set (match_operand:SF 0 "register_operand" "=r,x")
2454 (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2457 [(set_attr "type" "spadd,spadd")])
2459 (define_insn "fix_truncdfsi2"
2460 [(set (match_operand:SI 0 "register_operand" "=r,r")
2461 (fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2464 [(set_attr "type" "dpadd,dpadd")])
2466 (define_insn "fix_truncsfsi2"
2467 [(set (match_operand:SI 0 "register_operand" "=r,r")
2468 (fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2471 [(set_attr "type" "spadd,dpadd")])
2474 ;;- arithmetic instructions
2475 ;;- add instructions
2477 (define_insn "addsi3"
2478 [(set (match_operand:SI 0 "register_operand" "=r,r")
2479 (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2480 (match_operand:SI 2 "add_operand" "rI,J")))]
2486 ;; patterns for mixed mode floating point.
2487 ;; Do not define patterns that utilize mixed mode arithmetic that result
2488 ;; in narrowing the precision, because it loses accuracy, since the standard
2489 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2491 (define_expand "adddf3"
2492 [(set (match_operand:DF 0 "register_operand" "=r,x")
2493 (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2494 (match_operand:DF 2 "general_operand" "r,x")))]
2498 operands[1] = legitimize_operand (operands[1], DFmode);
2499 operands[2] = legitimize_operand (operands[2], DFmode);
2503 [(set (match_operand:DF 0 "register_operand" "=r,x")
2504 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2505 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2508 [(set_attr "type" "spadd")])
2511 [(set (match_operand:DF 0 "register_operand" "=r,x")
2512 (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2513 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2516 [(set_attr "type" "dpadd")])
2519 [(set (match_operand:DF 0 "register_operand" "=r,x")
2520 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2521 (match_operand:DF 2 "register_operand" "r,x")))]
2524 [(set_attr "type" "dpadd")])
2527 [(set (match_operand:DF 0 "register_operand" "=r,x")
2528 (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2529 (match_operand:DF 2 "register_operand" "r,x")))]
2532 [(set_attr "type" "dpadd")])
2534 (define_insn "addsf3"
2535 [(set (match_operand:SF 0 "register_operand" "=r,x")
2536 (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2537 (match_operand:SF 2 "register_operand" "r,x")))]
2540 [(set_attr "type" "spadd")])
2543 [(set (match_operand:DI 0 "register_operand" "=r")
2544 (plus:DI (match_operand:DI 1 "register_operand" "r")
2546 (match_operand:SI 2 "register_operand" "r"))))
2547 (clobber (reg:CC 0))]
2549 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2550 [(set_attr "type" "marith")])
2553 [(set (match_operand:DI 0 "register_operand" "=r")
2554 (plus:DI (zero_extend:DI
2555 (match_operand:SI 1 "register_operand" "r"))
2556 (match_operand:DI 2 "register_operand" "r")))
2557 (clobber (reg:CC 0))]
2559 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2560 [(set_attr "type" "marith")])
2562 (define_insn "adddi3"
2563 [(set (match_operand:DI 0 "register_operand" "=r")
2564 (plus:DI (match_operand:DI 1 "register_operand" "%r")
2565 (match_operand:DI 2 "register_operand" "r")))
2566 (clobber (reg:CC 0))]
2568 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2569 [(set_attr "type" "marith")])
2571 ;; Add with carry insns.
2574 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2575 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2576 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2578 (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2580 "addu.co %r0,%r1,%r2")
2583 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2584 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2587 "addu.co %#r0,%r0,%r1")
2590 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2591 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2592 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2595 "addu.ci %r0,%r1,%r2")
2597 ;;- subtract instructions
2599 (define_insn "subsi3"
2600 [(set (match_operand:SI 0 "register_operand" "=r")
2601 (minus:SI (match_operand:SI 1 "register_operand" "r")
2602 (match_operand:SI 2 "arith32_operand" "rI")))]
2606 ;; patterns for mixed mode floating point
2607 ;; Do not define patterns that utilize mixed mode arithmetic that result
2608 ;; in narrowing the precision, because it loses accuracy, since the standard
2609 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2611 (define_expand "subdf3"
2612 [(set (match_operand:DF 0 "register_operand" "=r,x")
2613 (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2614 (match_operand:DF 2 "general_operand" "r,x")))]
2618 operands[1] = legitimize_operand (operands[1], DFmode);
2619 operands[2] = legitimize_operand (operands[2], DFmode);
2623 [(set (match_operand:DF 0 "register_operand" "=r,x")
2624 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2625 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2628 [(set_attr "type" "spadd")])
2631 [(set (match_operand:DF 0 "register_operand" "=r,x")
2632 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2633 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2636 [(set_attr "type" "dpadd")])
2639 [(set (match_operand:DF 0 "register_operand" "=r,x")
2640 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2641 (match_operand:DF 2 "register_operand" "r,x")))]
2644 [(set_attr "type" "dpadd")])
2647 [(set (match_operand:DF 0 "register_operand" "=r,x")
2648 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2649 (match_operand:DF 2 "register_operand" "r,x")))]
2652 [(set_attr "type" "dpadd")])
2654 (define_insn "subsf3"
2655 [(set (match_operand:SF 0 "register_operand" "=r,x")
2656 (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2657 (match_operand:SF 2 "register_operand" "r,x")))]
2660 [(set_attr "type" "spadd")])
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (minus:DI (match_operand:DI 1 "register_operand" "r")
2666 (match_operand:SI 2 "register_operand" "r"))))
2667 (clobber (reg:CC 0))]
2669 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2670 [(set_attr "type" "marith")])
2673 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (minus:DI (zero_extend:DI
2675 (match_operand:SI 1 "register_operand" "r"))
2676 (match_operand:DI 2 "register_operand" "r")))
2677 (clobber (reg:CC 0))]
2679 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2680 [(set_attr "type" "marith")])
2682 (define_insn "subdi3"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (minus:DI (match_operand:DI 1 "register_operand" "r")
2685 (match_operand:DI 2 "register_operand" "r")))
2686 (clobber (reg:CC 0))]
2688 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2689 [(set_attr "type" "marith")])
2691 ;; Subtract with carry insns.
2694 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2695 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2696 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2698 (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2700 "subu.co %r0,%r1,%r2")
2703 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2704 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2707 "subu.co %#r0,%r0,%r1")
2710 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2711 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2712 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2715 "subu.ci %r0,%r1,%r2")
2717 ;;- multiply instructions
2719 ;; There is an unfounded silicon errata for E.1 requiring that an
2720 ;; immediate constant value in div/divu/mul instructions be less than
2721 ;; 0x800. This is no longer provided for.
2723 (define_insn "mulsi3"
2724 [(set (match_operand:SI 0 "register_operand" "=r")
2725 (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2726 (match_operand:SI 2 "arith32_operand" "rI")))]
2729 [(set_attr "type" "imul")])
2731 (define_insn "umulsidi3"
2732 [(set (match_operand:DI 0 "register_operand" "=r")
2733 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2734 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2737 [(set_attr "type" "imul")])
2739 ;; patterns for mixed mode floating point
2740 ;; Do not define patterns that utilize mixed mode arithmetic that result
2741 ;; in narrowing the precision, because it loses accuracy, since the standard
2742 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2744 (define_expand "muldf3"
2745 [(set (match_operand:DF 0 "register_operand" "=r,x")
2746 (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2747 (match_operand:DF 2 "general_operand" "r,x")))]
2751 operands[1] = legitimize_operand (operands[1], DFmode);
2752 operands[2] = legitimize_operand (operands[2], DFmode);
2756 [(set (match_operand:DF 0 "register_operand" "=r,x")
2757 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2758 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2761 [(set_attr "type" "spmul")])
2764 [(set (match_operand:DF 0 "register_operand" "=r,x")
2765 (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2766 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2769 [(set_attr "type" "spmul")])
2772 [(set (match_operand:DF 0 "register_operand" "=r,x")
2773 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2774 (match_operand:DF 2 "register_operand" "r,x")))]
2777 [(set_attr "type" "spmul")])
2780 [(set (match_operand:DF 0 "register_operand" "=r,x")
2781 (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2782 (match_operand:DF 2 "register_operand" "r,x")))]
2785 [(set_attr "type" "dpmul")])
2787 (define_insn "mulsf3"
2788 [(set (match_operand:SF 0 "register_operand" "=r,x")
2789 (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2790 (match_operand:SF 2 "register_operand" "r,x")))]
2793 [(set_attr "type" "spmul")])
2795 ;;- divide instructions
2797 ;; The 88k div and divu instructions don't reliably trap on
2798 ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The
2799 ;; general scheme for doing divide is to do a 4-way split based on the
2800 ;; sign of the two operand and do the appropriate negates.
2802 ;; The conditional trap instruction is not used as this serializes the
2803 ;; processor. Instead a conditional branch and an unconditional trap
2804 ;; are used, but after the divu. Since the divu takes up to 38 cycles,
2805 ;; the conditional branch is essentially free.
2807 ;; Two target options control how divide is done. One options selects
2808 ;; whether to do the branch and negate scheme instead of using the div
2809 ;; instruction; the other option selects whether to explicitly check
2810 ;; for divide-by-zero or take your chances. If the div instruction is
2811 ;; used, the O/S must complete the operation if the operands are
2812 ;; negative. The O/S will signal an overflow condition if the most
2813 ;; negative number (-2147483648) is divided by negative 1.
2815 ;; There is an unfounded silicon errata for E.1 requiring that an
2816 ;; immediate constant value in div/divu/mul instructions be less than
2817 ;; 0x800. This is no longer provided for.
2819 ;; Division by 0 trap
2820 (define_insn "trap_divide_by_zero"
2821 [(trap_if (const_int 1) 503)]
2824 [(set_attr "type" "weird")])
2826 ;; Conditional division by 0 trap.
2827 (define_expand "tcnd_divide_by_zero"
2829 (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2832 (match_operand 1 "" "")))
2833 (trap_if (const_int 1) 503)]
2837 emit_insn (gen_cmpsi (operands[0], const0_rtx));
2838 emit_jump_insn (gen_bne (operands[1]));
2839 emit_insn (gen_trap_divide_by_zero ());
2843 (define_expand "divsi3"
2844 [(set (match_operand:SI 0 "register_operand" "")
2845 (div:SI (match_operand:SI 1 "arith32_operand" "")
2846 (match_operand:SI 2 "arith32_operand" "")))]
2850 rtx op0 = operands[0];
2851 rtx op1 = operands[1];
2852 rtx op2 = operands[2];
2855 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making
2856 it a runtime (perhaps quite special). */
2858 if (GET_CODE (op1) == CONST_INT)
2859 op1 = force_reg (SImode, op1);
2861 else if (GET_CODE (op2) == CONST_INT
2862 && ! SMALL_INT (operands[2]))
2863 op2 = force_reg (SImode, op2);
2865 if (op2 == const0_rtx)
2867 emit_insn (gen_trap_divide_by_zero ());
2868 emit_insn (gen_dummy (op0));
2874 emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
2875 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2877 rtx label = gen_label_rtx ();
2878 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2880 emit_insn (gen_dummy (op0));
2885 join_label = gen_label_rtx ();
2886 if (GET_CODE (op1) == CONST_INT)
2889 rtx neg_op2 = gen_reg_rtx (SImode);
2890 rtx label1 = gen_label_rtx ();
2892 if (INTVAL (op1) < 0)
2895 op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
2897 op1 = force_reg (SImode, op1);
2899 emit_insn (gen_negsi2 (neg_op2, op2));
2900 emit_insn (gen_cmpsi (op2, const0_rtx));
2901 emit_jump_insn (gen_bgt (label1));
2902 /* constant / 0-or-negative */
2903 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2905 emit_insn (gen_negsi2 (op0, op0));
2907 if (TARGET_CHECK_ZERO_DIV)
2908 emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2909 emit_jump_insn (gen_jump (join_label));
2912 emit_label (label1); /* constant / positive */
2913 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2915 emit_insn (gen_negsi2 (op0, op0));
2918 else if (GET_CODE (op2) == CONST_INT)
2921 rtx neg_op1 = gen_reg_rtx (SImode);
2922 rtx label1 = gen_label_rtx ();
2924 if (INTVAL (op2) < 0)
2927 op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
2929 else if (! SMALL_INT (operands[2]))
2930 op2 = force_reg (SImode, op2);
2932 emit_insn (gen_negsi2 (neg_op1, op1));
2933 emit_insn (gen_cmpsi (op1, const0_rtx));
2934 emit_jump_insn (gen_bge (label1));
2935 /* 0-or-negative / constant */
2936 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2938 emit_insn (gen_negsi2 (op0, op0));
2940 emit_jump_insn (gen_jump (join_label));
2943 emit_label (label1); /* positive / constant */
2944 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2946 emit_insn (gen_negsi2 (op0, op0));
2951 rtx neg_op1 = gen_reg_rtx (SImode);
2952 rtx neg_op2 = gen_reg_rtx (SImode);
2953 rtx label1 = gen_label_rtx ();
2954 rtx label2 = gen_label_rtx ();
2955 rtx label3 = gen_label_rtx ();
2958 emit_insn (gen_negsi2 (neg_op2, op2));
2959 emit_insn (gen_cmpsi (op2, const0_rtx));
2960 emit_jump_insn (gen_bgt (label1));
2962 emit_insn (gen_negsi2 (neg_op1, op1));
2963 emit_insn (gen_cmpsi (op1, const0_rtx));
2964 emit_jump_insn (gen_bge (label2));
2965 /* negative / negative-or-0 */
2966 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
2968 if (TARGET_CHECK_ZERO_DIV)
2970 label4 = gen_label_rtx ();
2971 emit_insn (gen_cmpsi (op2, const0_rtx));
2972 emit_jump_insn (gen_bne (join_label));
2973 emit_label (label4);
2974 emit_insn (gen_trap_divide_by_zero ());
2976 emit_jump_insn (gen_jump (join_label));
2979 emit_label (label2); /* pos.-or-0 / neg.-or-0 */
2980 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2982 if (TARGET_CHECK_ZERO_DIV)
2984 emit_insn (gen_cmpsi (op2, const0_rtx));
2985 emit_jump_insn (gen_beq (label4));
2988 emit_insn (gen_negsi2 (op0, op0));
2989 emit_jump_insn (gen_jump (join_label));
2992 emit_label (label1);
2993 emit_insn (gen_negsi2 (neg_op1, op1));
2994 emit_insn (gen_cmpsi (op1, const0_rtx));
2995 emit_jump_insn (gen_bge (label3));
2996 /* negative / positive */
2997 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2998 emit_insn (gen_negsi2 (op0, op0));
2999 emit_jump_insn (gen_jump (join_label));
3002 emit_label (label3); /* positive-or-0 / positive */
3003 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
3006 emit_label (join_label);
3008 emit_insn (gen_dummy (op0));
3013 [(set (match_operand:SI 0 "register_operand" "=r")
3014 (div:SI (match_operand:SI 1 "register_operand" "r")
3015 (match_operand:SI 2 "arith_operand" "rI")))]
3018 [(set_attr "type" "idiv")])
3020 (define_expand "udivsi3"
3021 [(set (match_operand:SI 0 "register_operand" "")
3022 (udiv:SI (match_operand:SI 1 "register_operand" "")
3023 (match_operand:SI 2 "arith32_operand" "")))]
3027 rtx op2 = operands[2];
3029 if (op2 == const0_rtx)
3031 emit_insn (gen_trap_divide_by_zero ());
3032 emit_insn (gen_dummy (operands[0]));
3035 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3037 rtx label = gen_label_rtx ();
3038 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3039 gen_rtx (UDIV, SImode, operands[1], op2)));
3040 emit_insn (gen_tcnd_divide_by_zero (op2, label));
3042 emit_insn (gen_dummy (operands[0]));
3048 [(set (match_operand:SI 0 "register_operand" "=r")
3049 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3050 (match_operand:SI 2 "arith32_operand" "rI")))]
3051 "operands[2] != const0_rtx"
3053 [(set_attr "type" "idiv")])
3056 [(set (match_operand:SI 0 "register_operand" "=r")
3057 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3061 [(set_attr "type" "weird")])
3063 ;; patterns for mixed mode floating point.
3064 ;; Do not define patterns that utilize mixed mode arithmetic that result
3065 ;; in narrowing the precision, because it loses accuracy, since the standard
3066 ;; requires double rounding, whereas the 88000 instruction only rounds once.
3068 (define_expand "divdf3"
3069 [(set (match_operand:DF 0 "register_operand" "=r,x")
3070 (div:DF (match_operand:DF 1 "general_operand" "r,x")
3071 (match_operand:DF 2 "general_operand" "r,x")))]
3075 operands[1] = legitimize_operand (operands[1], DFmode);
3076 if (real_power_of_2_operand (operands[2]))
3078 union real_extract u;
3079 bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
3080 emit_insn (gen_muldf3 (operands[0], operands[1],
3081 CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
3084 else if (! register_operand (operands[2], DFmode))
3085 operands[2] = force_reg (DFmode, operands[2]);
3089 [(set (match_operand:DF 0 "register_operand" "=r,x")
3090 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3091 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3094 [(set_attr "type" "dpdiv")])
3097 [(set (match_operand:DF 0 "register_operand" "=r,x")
3098 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3099 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3102 [(set_attr "type" "dpdiv")])
3105 [(set (match_operand:DF 0 "register_operand" "=r,x")
3106 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3107 (match_operand:DF 2 "register_operand" "r,x")))]
3110 [(set_attr "type" "dpdiv")])
3112 (define_insn "divsf3"
3113 [(set (match_operand:SF 0 "register_operand" "=r,x")
3114 (div:SF (match_operand:SF 1 "register_operand" "r,x")
3115 (match_operand:SF 2 "register_operand" "r,x")))]
3118 [(set_attr "type" "spdiv")])
3121 [(set (match_operand:DF 0 "register_operand" "=r,x")
3122 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3123 (match_operand:DF 2 "register_operand" "r,x")))]
3126 [(set_attr "type" "dpdiv")])
3128 ;; - remainder instructions, don't define, since the hardware doesn't have any
3129 ;; direct support, and GNU can synthesis them out of div/mul just fine.
3131 ;;- load effective address, must come after add, so that we favor using
3132 ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require
3133 ;; the data unit), and also future 88k chips might not support unscaled
3134 ;; lda instructions.
3137 [(set (match_operand:SI 0 "register_operand" "=r")
3138 (match_operand:SI 1 "address_operand" "p"))]
3139 "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
3143 [(set (match_operand:SI 0 "register_operand" "=r")
3144 (match_operand:HI 1 "address_operand" "p"))]
3147 [(set_attr "type" "loada")])
3150 [(set (match_operand:SI 0 "register_operand" "=r")
3151 (match_operand:SI 1 "address_operand" "p"))]
3154 [(set_attr "type" "loada")])
3157 [(set (match_operand:SI 0 "register_operand" "=r")
3158 (match_operand:DI 1 "address_operand" "p"))]
3161 [(set_attr "type" "loada")])
3164 [(set (match_operand:SI 0 "register_operand" "=r")
3165 (match_operand:SF 1 "address_operand" "p"))]
3168 [(set_attr "type" "loada")])
3171 [(set (match_operand:SI 0 "register_operand" "=r")
3172 (match_operand:DF 1 "address_operand" "p"))]
3175 [(set_attr "type" "loada")])
3177 ;;- and instructions (with complement also)
3179 [(set (match_operand:SI 0 "register_operand" "=r")
3180 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3181 (match_operand:SI 2 "register_operand" "r")))]
3185 ;; If the operation is being performed on a 32-bit constant such that
3186 ;; it cannot be done in one insn, do it in two. We may lose a bit on
3187 ;; CSE in pathological cases, but it seems better doing it this way.
3189 (define_expand "andsi3"
3190 [(set (match_operand:SI 0 "register_operand" "")
3191 (and:SI (match_operand:SI 1 "arith32_operand" "")
3192 (match_operand:SI 2 "arith32_operand" "")))]
3196 if (GET_CODE (operands[2]) == CONST_INT)
3198 int value = INTVAL (operands[2]);
3200 if (! (SMALL_INTVAL (value)
3201 || (value & 0xffff0000) == 0xffff0000
3202 || (value & 0xffff) == 0xffff
3203 || (value & 0xffff) == 0
3204 || integer_ok_for_set (~value)))
3206 emit_insn (gen_andsi3 (operands[0], operands[1],
3207 gen_rtx (CONST_INT, VOIDmode,
3209 operands[1] = operands[0];
3210 operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
3216 [(set (match_operand:SI 0 "register_operand" "=r,r")
3217 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3218 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3220 "* return output_and (operands);"
3221 [(set_attr "type" "arith,marith")])
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3226 (match_operand:DI 2 "register_operand" "r")))]
3228 "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3229 [(set_attr "type" "marith")])
3231 (define_insn "anddi3"
3232 [(set (match_operand:DI 0 "register_operand" "=r")
3233 (and:DI (match_operand:DI 1 "arith64_operand" "%r")
3234 (match_operand:DI 2 "arith64_operand" "rn")))]
3240 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3241 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3242 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3244 output_asm_insn (output_and (xoperands), xoperands);
3246 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3247 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3248 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3250 return output_and (operands);
3252 [(set_attr "type" "marith")
3253 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3255 ;;- Bit set (inclusive or) instructions (with complement also)
3257 [(set (match_operand:SI 0 "register_operand" "=r")
3258 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3259 (match_operand:SI 2 "register_operand" "r")))]
3263 (define_expand "iorsi3"
3264 [(set (match_operand:SI 0 "register_operand" "")
3265 (ior:SI (match_operand:SI 1 "arith32_operand" "")
3266 (match_operand:SI 2 "arith32_operand" "")))]
3270 if (GET_CODE (operands[2]) == CONST_INT)
3272 int value = INTVAL (operands[2]);
3274 if (! (SMALL_INTVAL (value)
3275 || (value & 0xffff) == 0
3276 || integer_ok_for_set (value)))
3278 emit_insn (gen_iorsi3 (operands[0], operands[1],
3279 gen_rtx (CONST_INT, VOIDmode,
3280 value & 0xffff0000)));
3281 operands[1] = operands[0];
3282 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3288 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3289 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3290 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3296 or.u %0,%1,%X2\;or %0,%0,%x2"
3297 [(set_attr "type" "arith,arith,bit,marith")])
3300 [(set (match_operand:DI 0 "register_operand" "=r")
3301 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3302 (match_operand:DI 2 "register_operand" "r")))]
3304 "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3305 [(set_attr "type" "marith")])
3307 (define_insn "iordi3"
3308 [(set (match_operand:DI 0 "register_operand" "=r")
3309 (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3310 (match_operand:DI 2 "arith64_operand" "rn")))]
3316 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3317 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3318 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3320 output_asm_insn (output_ior (xoperands), xoperands);
3322 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3323 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3324 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3326 return output_ior (operands);
3328 [(set_attr "type" "marith")
3329 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3331 ;;- xor instructions (with complement also)
3333 [(set (match_operand:SI 0 "register_operand" "=r")
3334 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3335 (match_operand:SI 2 "register_operand" "r"))))]
3339 (define_expand "xorsi3"
3340 [(set (match_operand:SI 0 "register_operand" "")
3341 (xor:SI (match_operand:SI 1 "arith32_operand" "")
3342 (match_operand:SI 2 "arith32_operand" "")))]
3346 if (GET_CODE (operands[2]) == CONST_INT)
3348 int value = INTVAL (operands[2]);
3350 if (! (SMALL_INTVAL (value)
3351 || (value & 0xffff) == 0))
3353 emit_insn (gen_xorsi3 (operands[0], operands[1],
3354 gen_rtx (CONST_INT, VOIDmode,
3355 value & 0xffff0000)));
3356 operands[1] = operands[0];
3357 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3363 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3364 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3365 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3370 xor.u %0,%1,%X2\;xor %0,%0,%x2"
3371 [(set_attr "type" "arith,arith,marith")])
3374 [(set (match_operand:DI 0 "register_operand" "=r")
3375 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3376 (match_operand:DI 2 "register_operand" "r"))))]
3378 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3379 [(set_attr "type" "marith")])
3381 (define_insn "xordi3"
3382 [(set (match_operand:DI 0 "register_operand" "=r")
3383 (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3384 (match_operand:DI 2 "arith64_operand" "rn")))]
3390 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3391 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3392 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3394 output_asm_insn (output_xor (xoperands), xoperands);
3396 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3397 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3398 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3400 return output_xor (operands);
3402 [(set_attr "type" "marith")
3403 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3405 ;;- ones complement instructions
3406 (define_insn "one_cmplsi2"
3407 [(set (match_operand:SI 0 "register_operand" "=r")
3408 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3412 (define_insn "one_cmpldi2"
3413 [(set (match_operand:DI 0 "register_operand" "=r")
3414 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3416 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3417 [(set_attr "type" "marith")])
3419 ;; Optimized special cases of shifting.
3420 ;; Must precede the general case.
3422 ;; @@ What about HImode shifted by 8?
3425 [(set (match_operand:SI 0 "register_operand" "=r")
3426 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3428 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3430 [(set_attr "type" "load")])
3433 [(set (match_operand:SI 0 "register_operand" "=r")
3434 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3436 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3438 [(set_attr "type" "load")])
3441 [(set (match_operand:SI 0 "register_operand" "=r")
3442 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3444 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3446 [(set_attr "type" "load")])
3449 [(set (match_operand:SI 0 "register_operand" "=r")
3450 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3452 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3454 [(set_attr "type" "load")])
3456 ;;- arithmetic shift instructions.
3458 ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should
3459 ;; be arith32_operand?
3461 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3463 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3464 (match_operand:SI 1 "arith_operand" "rI"))
3468 [(set_attr "type" "weird")])
3470 ;; Just in case the optimizer decides to fold away the test.
3472 [(trap_if (const_int 1) 7)]
3475 [(set_attr "type" "weird")])
3477 (define_expand "ashlsi3"
3478 [(set (match_operand:SI 0 "register_operand" "")
3479 (ashift:SI (match_operand:SI 1 "register_operand" "")
3480 (match_operand:SI 2 "arith32_operand" "")))]
3484 if (GET_CODE (operands[2]) == CONST_INT)
3486 if ((unsigned) INTVAL (operands[2]) > 31)
3488 if (TARGET_TRAP_LARGE_SHIFT)
3489 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3490 gen_rtx (CONST_INT, VOIDmode, 31)));
3492 emit_move_insn (operands[0], const0_rtx);
3497 else if (TARGET_TRAP_LARGE_SHIFT)
3498 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3500 else if (TARGET_HANDLE_LARGE_SHIFT)
3502 rtx reg = gen_reg_rtx (SImode);
3503 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3504 emit_insn (gen_sleu (reg));
3505 emit_insn (gen_andsi3 (reg, operands[1], reg));
3511 [(set (match_operand:SI 0 "register_operand" "=r,r")
3512 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3513 (match_operand:SI 2 "arith5_operand" "r,K")))]
3518 [(set_attr "type" "bit")])
3520 (define_expand "ashrsi3"
3521 [(set (match_operand:SI 0 "register_operand" "")
3522 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3523 (match_operand:SI 2 "arith32_operand" "")))]
3527 if (GET_CODE (operands[2]) == CONST_INT)
3529 if ((unsigned) INTVAL (operands[2]) > 31)
3531 if (TARGET_TRAP_LARGE_SHIFT)
3533 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3534 gen_rtx (CONST_INT, VOIDmode, 31)));
3538 operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
3542 else if (TARGET_TRAP_LARGE_SHIFT)
3543 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3545 else if (TARGET_HANDLE_LARGE_SHIFT)
3547 rtx reg = gen_reg_rtx (SImode);
3548 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3549 emit_insn (gen_sgtu (reg));
3550 emit_insn (gen_iorsi3 (reg, operands[2], reg));
3556 [(set (match_operand:SI 0 "register_operand" "=r,r")
3557 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3558 (match_operand:SI 2 "arith5_operand" "r,K")))]
3563 [(set_attr "type" "bit")])
3565 ;;- logical shift instructions. Logical shift left becomes arithmetic
3568 (define_expand "lshrsi3"
3569 [(set (match_operand:SI 0 "register_operand" "")
3570 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3571 (match_operand:SI 2 "arith32_operand" "")))]
3575 if (GET_CODE (operands[2]) == CONST_INT)
3577 if ((unsigned) INTVAL (operands[2]) > 31)
3579 if (TARGET_TRAP_LARGE_SHIFT)
3580 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3581 gen_rtx (CONST_INT, VOIDmode, 31)));
3583 emit_move_insn (operands[0], const0_rtx);
3588 else if (TARGET_TRAP_LARGE_SHIFT)
3589 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3591 else if (TARGET_HANDLE_LARGE_SHIFT)
3593 rtx reg = gen_reg_rtx (SImode);
3594 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3595 emit_insn (gen_sleu (reg));
3596 emit_insn (gen_andsi3 (reg, operands[1], reg));
3602 [(set (match_operand:SI 0 "register_operand" "=r,r")
3603 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3604 (match_operand:SI 2 "arith5_operand" "r,K")))]
3609 [(set_attr "type" "bit")])
3611 ;;- rotate instructions
3613 (define_expand "rotlsi3"
3614 [(set (match_operand:SI 0 "register_operand" "")
3615 (rotatert:SI (match_operand:SI 1 "register_operand" "")
3616 (match_operand:SI 2 "arith32_operand" "")))]
3620 if (GET_CODE (operands[2]) == CONST_INT
3621 && (unsigned) INTVAL (operands[2]) >= 32)
3622 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3623 (32 - INTVAL (operands[2])) % 32);
3626 rtx op = gen_reg_rtx (SImode);
3627 emit_insn (gen_negsi2 (op, operands[2]));
3632 (define_insn "rotrsi3"
3633 [(set (match_operand:SI 0 "register_operand" "=r")
3634 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3635 (match_operand:SI 2 "arith_operand" "rI")))]
3638 [(set_attr "type" "bit")])
3642 ;; The ff1 instruction searches from the most significant bit while ffs
3643 ;; searches from the least significant bit. The bit index and treatment of
3644 ;; zero also differ. This amazing sequence was discovered using the GNU
3647 (define_insn "ffssi2"
3648 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3649 (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3650 (clobber (reg:CC 0))
3651 (clobber (match_scratch:SI 2 "=r,X"))]
3654 subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3655 subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3656 [(set_attr "type" "marith")
3657 (set_attr "length" "4")])
3659 ;; Bit field instructions.
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3670 [(set (match_operand:SI 0 "register_operand" "=r")
3671 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3672 (match_operand:SI 2 "int5_operand" "")
3673 (match_operand:SI 3 "int5_operand" "")))]
3677 operands[4] = gen_rtx (CONST_INT, SImode,
3678 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3679 return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3681 [(set_attr "type" "bit")])
3684 [(set (match_operand:SI 0 "register_operand" "=r")
3685 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3691 (define_insn "extzv"
3692 [(set (match_operand:SI 0 "register_operand" "=r")
3693 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3694 (match_operand:SI 2 "int5_operand" "")
3695 (match_operand:SI 3 "int5_operand" "")))]
3699 operands[4] = gen_rtx (CONST_INT, SImode,
3700 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3701 return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
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" ""))
3713 operands[3] = gen_rtx (CONST_INT, SImode,
3714 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3715 return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3717 [(set_attr "type" "bit")])
3720 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3721 (match_operand:SI 1 "int5_operand" "")
3722 (match_operand:SI 2 "int5_operand" ""))
3727 operands[3] = gen_rtx (CONST_INT, SImode,
3728 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3729 return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3731 [(set_attr "type" "bit")])
3734 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3735 (match_operand:SI 1 "int5_operand" "")
3736 (match_operand:SI 2 "int5_operand" ""))
3737 (match_operand:SI 3 "int32_operand" "n"))]
3741 int value = INTVAL (operands[3]);
3743 if (INTVAL (operands[1]) < 32)
3744 value &= (1 << INTVAL (operands[1])) - 1;
3746 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3747 32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3749 value <<= INTVAL (operands[2]);
3750 operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
3752 if (SMALL_INTVAL (value))
3753 return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3754 else if ((value & 0x0000ffff) == 0)
3755 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3757 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3759 [(set_attr "type" "marith")
3760 (set_attr "length" "3")]) ; may be 2 or 3.
3763 (define_insn "negsi2"
3764 [(set (match_operand:SI 0 "register_operand" "=r")
3765 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3770 [(set (match_operand:SF 0 "register_operand" "=r,x")
3771 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3775 fsub.ssd %0,%#x0,%1"
3776 [(set_attr "type" "dpadd")])
3778 (define_insn "negdf2"
3779 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3780 (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3783 xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3785 [(set_attr "type" "marith,arith")])
3787 (define_insn "negsf2"
3788 [(set (match_operand:SF 0 "register_operand" "=r")
3789 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3791 "xor.u %0,%1,0x8000")
3793 ;; absolute value insns for floating-point (integer abs can be done using the
3794 ;; machine-independent sequence).
3796 (define_insn "absdf2"
3797 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3798 (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3801 and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3803 [(set_attr "type" "marith,arith")])
3805 (define_insn "abssf2"
3806 [(set (match_operand:SF 0 "register_operand" "=r")
3807 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3809 "and.u %0,%1,0x7fff")
3811 ;; Subroutines of "casesi".
3813 ;; Operand 0 is index
3814 ;; operand 1 is the minimum bound
3815 ;; operand 2 is the maximum bound - minimum bound + 1
3816 ;; operand 3 is CODE_LABEL for the table;
3817 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3819 (define_expand "casesi"
3820 ;; We don't use these for generating the RTL, but we must describe
3821 ;; the operands here.
3822 [(match_operand:SI 0 "general_operand" "")
3823 (match_operand:SI 1 "immediate_operand" "")
3824 (match_operand:SI 2 "immediate_operand" "")
3825 (match_operand 3 "" "")
3826 (match_operand 4 "" "")]
3830 register rtx index_diff = gen_reg_rtx (SImode);
3831 register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
3832 register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
3835 if (! CASE_VECTOR_INSNS)
3836 /* These instructions are likely to be scheduled and made loop invariant.
3837 This decreases the cost of the dispatch at the expense of the default
3839 base = force_reg (SImode, memory_address_noforce (SImode, label));
3841 /* Compute the index difference and handle the default case. */
3842 emit_insn (gen_addsi3 (index_diff,
3843 force_reg (SImode, operands[0]),
3844 ADD_INT (low) ? low : force_reg (SImode, low)));
3845 emit_insn (gen_cmpsi (index_diff, operands[2]));
3846 /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3847 entry to the table. However, that doesn't seem to win on the m88110. */
3848 emit_jump_insn (gen_bgtu (operands[4]));
3850 if (CASE_VECTOR_INSNS)
3851 /* Call the jump that will branch to the appropriate case. */
3852 emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3854 /* Load the table entry and jump to it. */
3855 emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3857 /* Claim that flow drops into the table so it will be adjacent by not
3858 emitting a barrier. */
3862 (define_expand "casesi_jump"
3863 [(set (match_operand:SI 0 "" "")
3864 (mem:SI (plus:SI (match_operand:SI 1 "" "")
3865 (mult:SI (match_operand:SI 2 "" "")
3867 (parallel [(set (pc) (match_dup 0))
3868 (use (label_ref (match_operand 3 "" "")))])]
3873 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3874 (use (label_ref (match_operand 1 "" "")))]
3877 [(set_attr "type" "jump")])
3879 ;; The bsr.n instruction is directed to the END of the table. See
3880 ;; ASM_OUTPUT_CASE_END.
3882 (define_insn "casesi_enter"
3883 [(set (pc) (match_operand 0 "" ""))
3884 (use (match_operand:SI 1 "register_operand" "r"))
3885 ;; The USE here is so that at least one jump-insn will refer to the label,
3886 ;; to keep it alive in jump_optimize.
3887 (use (label_ref (match_operand 2 "" "")))
3888 (clobber (reg:SI 1))]
3892 if (flag_delayed_branch)
3893 return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3894 m88k_case_index = REGNO (operands[1]);
3897 [(set_attr "type" "weird")
3898 (set_attr "length" "3")]) ; Including the "jmp r1".
3900 ;;- jump to subroutine
3901 (define_expand "call"
3902 [(parallel [(call (match_operand:SI 0 "" "")
3903 (match_operand 1 "" ""))
3904 (clobber (reg:SI 1))])]
3908 if (GET_CODE (operands[0]) == MEM
3909 && ! call_address_operand (XEXP (operands[0], 0), SImode))
3910 operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
3911 force_reg (Pmode, XEXP (operands[0], 0)));
3915 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3916 (match_operand 1 "" ""))
3917 (clobber (reg:SI 1))])]
3919 "* return output_call (operands, operands[0]);"
3920 [(set_attr "type" "call")])
3922 (define_expand "call_value"
3923 [(parallel [(set (match_operand 0 "register_operand" "")
3924 (call (match_operand:SI 1 "" "")
3925 (match_operand 2 "" "")))
3926 (clobber (reg:SI 1))])]
3930 if (GET_CODE (operands[1]) == MEM
3931 && ! call_address_operand (XEXP (operands[1], 0), SImode))
3932 operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
3933 force_reg (Pmode, XEXP (operands[1], 0)));
3937 [(parallel [(set (match_operand 0 "register_operand" "=r")
3939 (match_operand:SI 1 "call_address_operand" "rQ"))
3940 (match_operand 2 "" "")))
3941 (clobber (reg:SI 1))])]
3943 "* return output_call (operands, operands[1]);"
3944 [(set_attr "type" "call")])
3946 ;; Nop instruction and others
3952 [(set_attr "type" "bit")])
3954 (define_insn "return"
3958 [(set_attr "type" "jump")])
3960 (define_expand "prologue"
3963 "m88k_expand_prologue (); DONE;")
3965 (define_expand "epilogue"
3967 "! null_prologue ()"
3968 "m88k_expand_epilogue ();")
3970 (define_insn "blockage"
3971 [(unspec_volatile [(const_int 0)] 0)]
3974 [(set_attr "length" "0")])
3976 (define_insn "indirect_jump"
3977 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3980 [(set_attr "type" "jump")])
3984 (label_ref (match_operand 0 "" "")))]
3987 [(set_attr "type" "jump")])
3989 ;; This insn is used for some loop tests, typically loops reversed when
3990 ;; strength reduction is used. It is actually created when the instruction
3991 ;; combination phase combines the special loop test. Since this insn
3992 ;; is both a jump insn and has an output, it must deal with it's own
3993 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
3994 ;; to not choose the register alternatives in the event a reload is needed.
3996 (define_expand "decrement_and_branch_until_zero"
3997 [(parallel [(set (pc)
3999 (match_operator 0 "relop_no_unsigned"
4000 [(match_operand:SI 1 "register_operand" "")
4002 (label_ref (match_operand 2 "" ""))
4005 (plus:SI (match_dup 1)
4006 (match_operand:SI 3 "add_operand" "")))
4007 (clobber (match_scratch:SI 4 ""))
4008 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))])]
4015 (match_operator 0 "relop_no_unsigned"
4016 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
4018 (label_ref (match_operand 2 "" ""))
4021 (plus:SI (match_dup 1)
4022 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
4023 (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
4024 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
4025 "find_reg_note (insn, REG_NONNEG, 0)"
4027 bcnd.n %B0,%1,%2\;addu %1,%1,%3
4028 bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4029 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4030 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4031 [(set_attr "type" "weird")
4032 (set_attr "length" "2,2,4,4")])
4034 ;; Special insn to serve as the last insn of a define_expand. This insn
4035 ;; will generate no code.
4037 (define_expand "dummy"
4038 [(set (match_operand 0 "" "") (match_dup 0))]