1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;; Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@mcc.com)
4 ;; Additional changes by Michael Meissner (meissner@osf.org)
5 ;; Currently supported by Tom Wood (wood@dg-rtp.dg.com)
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; SCCS rev field. This is a NOP, just to get the SCCS id into the
28 (define_expand "m88k_sccs_id"
29 [(match_operand:SI 0 "" "")]
31 "{ static char sccs_id[] = \"@(#)m88k.md 2.2.6.10 28 Jul 1992 10:22:08\";
34 ;; Attribute specifications
37 (define_attr "cpu" "m88100,m88110,m88000"
38 (const (symbol_ref "m88k_cpu")))
40 ; Type of each instruction. Default is arithmetic.
41 ; I'd like to write the list as this, but genattrtab won't accept it.
43 ; "branch,jump,call, ; flow-control instructions
44 ; load,store,loada, ; data unit instructions
45 ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
46 ; spmul,dpmul,imul, ; FPU multiply instructions
47 ; arith,bit,mov ; integer unit instructions
48 ; marith,weird" ; multi-word instructions
50 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
52 "branch,jump,call,load,store,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
53 (const_string "arith"))
55 ; Convenience attributes.
56 (define_attr "unit" "bit,memory,multiply,divide,fpadd,other"
57 (cond [(eq_attr "type" "bit") (const_string "bit")
58 (eq_attr "type" "load,store") (const_string "memory")
59 (eq_attr "type" "spmul,dpmul,imul") (const_string "multiply")
60 (eq_attr "type" "spdiv,dpdiv,idiv") (const_string "divide")
61 (eq_attr "type" "spadd,dpadd,spcmp,dpcmp") (const_string "fpadd")]
62 (const_string "other")))
64 (define_attr "fpu" "yes,no"
66 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
67 (const_string "yes") (const_string "no")))
69 ; Length in # of instructions of each insn. The values are not exact, but
71 (define_attr "length" ""
72 (cond [(eq_attr "type" "marith")
76 ; Describe a user's asm statement.
77 (define_asm_attributes
78 [(set_attr "type" "weird")])
80 ; Define the delay slot requirements for branches and calls.
81 ; The m88100 annuls instructions if a conditional branch is taken.
82 ; For insns of TYPE_BRANCH that are multi-word instructions, the
83 ; delay slot applies to the first instruction.
85 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
86 ; be a call or branch.
88 (define_delay (eq_attr "type" "branch,jump")
91 (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
92 (eq_attr "type" "!load")) ; issue as-soon-as-possible.
93 (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
94 (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
96 ; output_call supports an unconditional branch in the delay slot of
97 ; a call. (@@ Support for this case is expected in reorg.c soon.)
99 (define_delay (eq_attr "type" "call")
100 [(eq_attr "type" "!branch,call,marith,weird") ; required.
103 ; An abstract block diagram of the function units for the m88100.
110 ; ,----------'| | `----------------------.
112 ; load | store | | arith | | |
113 ; | | | +-v-v-+ | dp source
115 ; store | | | div +-v-v-+
116 ; ,------. | | | ,-----. ,-----------' `-----------.
118 ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+
119 ; | | stage 2 | | | `---| add 2 | | mul 2 |
120 ; | +---------+ | +--v--+ +-------+ imul +-------+
121 ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |
122 ; | +---------+ | +--v--+ +-------+ | +-------+
123 ; | | stage 0 | | | | add 4 | | | mul 4 |
124 ; | +--v---v--+ | | +---v---+ | +-------+
125 ; | | | | | | | | mul 5 |
126 ; | * | | | | | +---v---+
127 ; | | | | | +----v----+ |
128 ; | load | | | fp add `------>| fp last |<------' fp mul
129 ; | | | | +---v-v--^+
131 ; | | | | | `--' dp dest
132 ; | | +--v-----v--+ |
133 ; | `--->| writeback |<--------------------'
136 ; `------------------' *
138 ; The decode unit need not be specified.
139 ; Consideration of writeback contention is critical to superb scheduling.
141 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
142 ; TEST READY-DELAY BUSY-DELAY [CONFLICT-LIST])
144 ;(define_function_unit "decode" 1 1 (const_int 1) 0 1)
146 ; Describing the alu is currently not useful.
147 ;(define_function_unit "alu" 1 0 (eq_attr "type"
148 ; "!store,marith,weird") 1 0)
149 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
151 (define_function_unit "alu" 1 0
152 (and (eq_attr "type" "loada,arith,bit,mov") (eq_attr "cpu" "!m88100")) 2 0)
153 (define_function_unit "alu" 1 0
154 (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
156 (define_function_unit "memory" 1 3
157 (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 2)
158 (define_function_unit "memory" 1 3
159 (and (eq_attr "type" "load") (eq_attr "cpu" "!m88100")) 4 2)
161 ; The fp1 and fplast descriptions currently have no effect.
162 ;(define_function_unit "fp1" 1 1 (eq_attr "fpu" "yes") 1 2)
164 ; The times are adjusted to include fp1 and fplast, but then are further
165 ; adjusted based on the actual generated code. The notation to the right
166 ; is the total latency. A range denotes a group of instructions and/or
167 ; conditions (the extra clock of fplast time with some sequences).
168 (define_function_unit "fpmul" 1 4
169 (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 2) ; 6-8
170 (define_function_unit "fpmul" 1 4
171 (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 2) ; 9-10
172 (define_function_unit "fpmul" 1 4
173 (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 2) ; 4
175 (define_function_unit "fpmul" 1 4
176 (and (eq_attr "type" "imul,spmul,dpmul")
177 (eq_attr "cpu" "!m88100")) 6 2) ; 3
179 (define_function_unit "fpadd" 1 3
180 (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 2) ; 5-6
181 (define_function_unit "fpadd" 1 3
182 (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 2) ; 6-7
183 (define_function_unit "fpadd" 1 3
184 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 2) ; 30-31
185 (define_function_unit "fpadd" 1 3
186 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 2) ; 60-61
187 (define_function_unit "fpadd" 1 3
188 (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 2) ; 38
190 (define_function_unit "fpadd" 1 3
191 (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 6 2) ; 3
192 (define_function_unit "fpadd" 1 3
193 (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 3
194 (define_function_unit "fpadd" 1 3
195 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 26 2) ; 13
196 (define_function_unit "fpadd" 1 3
197 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 46 2) ; 23
198 (define_function_unit "fpadd" 1 3
199 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 36 2) ; 18
201 ;(define_function_unit "fplast" 1 1 (eq_attr "fpu" "yes") 1 2)
203 ; Describing writeback contention is currently not useful.
204 ;(define_function_unit "writeback" 1 1
205 ; (eq_attr "type" "!store,branch,jump,call") 0 1)
207 ; Describing stores is currently not useful. The suggestion here is that the
208 ; function unit ordering has already been established (writeback is last) and
209 ; that store insns use the units in an unusual order.
210 ;(define_function_unit "writeback" 1 1 (eq_attr "type" "store") 0 1)
211 ;(define_function_unit "memory" 1 3 (eq_attr "type" "store") 1 2)
213 ;; Superoptimizer sequences
215 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
220 [(set (match_operand:SI 0 "register_operand" "=r")
221 (minus:SI (match_operand:SI 1 "register_operand" "r")
222 (geu:SI (match_operand:SI 2 "register_operand" "r")
223 (match_operand:SI 3 "register_operand" "r"))))]
225 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
227 (plus:SI (match_dup 1)
228 (unspec:SI [(const_int 0)
232 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
237 [(set (match_operand:SI 0 "register_operand" "=r")
238 (minus:SI (match_operand:SI 1 "register_operand" "r")
239 (leu:SI (match_operand:SI 3 "register_operand" "r")
240 (match_operand:SI 2 "register_operand" "r"))))]
242 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
244 (plus:SI (match_dup 1)
245 (unspec:SI [(const_int 0)
249 ;; eq0+: { r = (v0 == 0) + v1; }
254 [(set (match_operand:SI 0 "register_operand" "=r")
255 (minus:SI (match_operand:SI 1 "register_operand" "r")
256 (eq:SI (match_operand:SI 2 "register_operand" "r")
259 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
261 (plus:SI (match_dup 1)
262 (unspec:SI [(const_int 0)
266 ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
271 [(set (match_operand:SI 0 "register_operand" "=r")
272 (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
273 (match_operand:SI 3 "register_operand" "r"))
274 (match_operand:SI 1 "register_operand" "r")))]
276 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
278 (minus:SI (match_dup 1)
279 (unspec:SI [(const_int 0)
283 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
288 [(set (match_operand:SI 0 "register_operand" "=r")
289 (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
290 (match_operand:SI 2 "register_operand" "r"))
291 (match_operand:SI 1 "register_operand" "r")))]
293 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
295 (minus:SI (match_dup 1)
296 (unspec:SI [(const_int 0)
300 ;; ne0-: { r = v1 - (v0 != 0); }
305 [(set (match_operand:SI 0 "register_operand" "=r")
306 (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
308 (match_operand:SI 1 "register_operand" "r")))]
310 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
312 (minus:SI (match_dup 1)
313 (unspec:SI [(const_int 0)
317 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
322 [(set (match_operand:SI 0 "register_operand" "=r")
323 (minus:SI (match_operand:SI 1 "register_operand" "r")
325 (match_operand:SI 2 "register_operand" "r")
329 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
331 (minus:SI (match_dup 1)
332 (unspec:SI [(const_int 0)
336 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
337 ;; (tege@sics.se). They've changed since then, so don't complain to him
338 ;; if they don't work right.
340 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. LSHIFT opcodes are
341 ;; not produced and should not normally occur. Also, the gen functions
342 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
343 ;; special needs to be done here.
345 ;; (a << int1) >> int2 optimizations into a single extract.
346 ;; These patterns need to occur before the normal shift patterns
349 [(set (match_operand:SI 0 "register_operand" "=r")
350 (ashiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
351 (match_operand:SI 2 "int5_operand" ""))
352 (match_operand:SI 3 "int5_operand" "")))]
353 "INTVAL (operands [2]) <= INTVAL (operands [3])"
356 operands[4] = gen_rtx (CONST_INT, SImode,
357 INTVAL (operands[3]) - INTVAL (operands[2]));
358 return \"ext %0,%1,%w3<%4>\"; /* <(%3-%2)> */
360 [(set_attr "type" "bit")])
363 [(set (match_operand:SI 0 "register_operand" "=r")
364 (lshiftrt:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
365 (match_operand:SI 2 "int5_operand" ""))
366 (match_operand:SI 3 "int5_operand" "")))]
367 "INTVAL (operands [2]) <= INTVAL (operands [3])"
370 operands[4] = gen_rtx (CONST_INT, SImode,
371 INTVAL (operands[3]) - INTVAL (operands[2]));
372 return \"extu %0,%1,%w3<%4>\"; /* <(%3-%2)> */
374 [(set_attr "type" "bit")])
376 ;; Optimize possible cases of the set instruction.
379 [(set (match_operand:SI 0 "register_operand" "=r")
380 (ashift:SI (const_int -1)
381 (match_operand:SI 1 "register_operand" "r")))]
384 [(set_attr "type" "bit")])
387 [(set (match_operand:SI 0 "register_operand" "=r")
388 (ior:SI (ashift:SI (const_int -1)
389 (match_operand:SI 1 "register_operand" "r"))
390 (match_operand:SI 2 "register_operand" "r")))]
393 [(set_attr "type" "bit")])
396 [(set (match_operand:SI 0 "register_operand" "=r")
397 (ior:SI (match_operand:SI 1 "register_operand" "r")
398 (ashift:SI (const_int -1)
399 (match_operand:SI 2 "register_operand" "r"))))]
402 [(set_attr "type" "bit")])
404 ;; Optimize possible cases of the mak instruction.
407 [(set (match_operand:SI 0 "register_operand" "=r")
408 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
409 (match_operand:SI 2 "int5_operand" ""))
410 (match_operand:SI 3 "immediate_operand" "n")))]
411 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
414 operands[4] = gen_rtx (CONST_INT, SImode,
415 exact_log2 (1 + (INTVAL (operands[3])
416 >> INTVAL(operands[2]))));
417 return \"mak %0,%1,%4<%2>\";
419 [(set_attr "type" "bit")])
421 ;; Optimize possible cases of output_and.
424 [(set (match_operand:SI 0 "register_operand" "=r")
425 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
426 (match_operand:SI 2 "int5_operand" "")
427 (match_operand:SI 3 "int5_operand" ""))
428 (match_operand:SI 4 "int5_operand" "")))]
429 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
433 = gen_rtx (CONST_INT, SImode,
434 ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
435 return output_and (operands);
437 [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.
439 ;; Improve logical operations on compare words
441 ;; We define all logical operations on CCmode values to preserve the pairwise
442 ;; relationship of the compare bits. This allows a future branch prediction
443 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
445 ;; Opportunities arise when conditional expressions using && and || are made
446 ;; unconditional. When these are used to branch, the sequence is
447 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create
448 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
449 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
451 ;; When the extracted conditions are the same, the define_split patterns
452 ;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed
453 ;; conditions match, one compare word can be complimented, resulting in
454 ;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.
455 ;; If the conditions don't line up, one can be rotated. To keep the pairwise
456 ;; relationship, it may be necessary to both rotate and compliment. Rotating
457 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
458 ;; we don't do this for ext/ext/{and,or}.
460 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
461 ;; into an alternate form of bb0 and bb1.
464 [(set (match_operand:SI 0 "register_operand" "=r")
466 (match_operator 1 "relop"
467 [(match_operand:CC 2 "register_operand" "%r")
470 (match_operator 3 "relop"
471 [(match_operand:CC 4 "register_operand" "r")
473 (clobber (match_operand:SI 5 "register_operand" "=r"))]
476 (ior:CC (match_dup 4)
479 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
480 "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
481 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
482 ; /* The conditions match. */
483 else if (GET_CODE (operands[1])
484 == reverse_condition (GET_CODE (operands[3])))
485 /* Reverse the condition by complimenting the compare word. */
486 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
489 /* Make the condition pairs line up by rotating the compare word. */
490 int cv1 = condition_value (operands[1]);
491 int cv2 = condition_value (operands[3]);
493 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
494 gen_rtx (CONST_INT, VOIDmode,
495 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
496 /* Reverse the condition if needed. */
497 if ((cv1 & 1) != (cv2 & 1))
498 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
502 [(set (match_operand:SI 0 "register_operand" "=r")
503 (ior:SI (match_operator 1 "relop"
504 [(match_operand:CC 2 "register_operand" "%r")
506 (match_operator 3 "relop"
507 [(match_operand:CC 4 "register_operand" "r")
509 (clobber (match_operand:SI 5 "register_operand" "=r"))]
510 "GET_CODE (operands[1]) == GET_CODE (operands[3])
511 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
513 (ior:CC (match_dup 4)
516 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
517 "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
518 /* Reverse the condition by complimenting the compare word. */
519 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
520 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
523 [(set (match_operand:SI 0 "register_operand" "=r")
525 (match_operator 1 "relop"
526 [(match_operand:CC 2 "register_operand" "%r")
529 (match_operator 3 "relop"
530 [(match_operand:CC 4 "register_operand" "r")
532 (clobber (match_operand:SI 5 "register_operand" "=r"))]
535 (and:CC (match_dup 4)
538 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
539 "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
540 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
541 ; /* The conditions match. */
542 else if (GET_CODE (operands[1])
543 == reverse_condition (GET_CODE (operands[3])))
544 /* Reverse the condition by complimenting the compare word. */
545 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
548 /* Make the condition pairs line up by rotating the compare word. */
549 int cv1 = condition_value (operands[1]);
550 int cv2 = condition_value (operands[3]);
552 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
553 gen_rtx (CONST_INT, VOIDmode,
554 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
555 /* Reverse the condition if needed. */
556 if ((cv1 & 1) != (cv2 & 1))
557 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
561 [(set (match_operand:SI 0 "register_operand" "=r")
562 (and:SI (match_operator 1 "relop"
563 [(match_operand:CC 2 "register_operand" "%r")
565 (match_operator 3 "relop"
566 [(match_operand:CC 4 "register_operand" "r")
568 (clobber (match_operand:SI 5 "register_operand" "=r"))]
569 "GET_CODE (operands[1]) == GET_CODE (operands[3])
570 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
572 (and:CC (match_dup 4)
575 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
576 "operands[5] = gen_rtx (SUBREG, CCmode, operands[5], 0);
577 /* Reverse the condition by complimenting the compare word. */
578 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
579 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
581 ;; Logical operations on compare words.
584 [(set (match_operand:CC 0 "register_operand" "=r")
585 (and:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
586 (match_operand:CC 2 "register_operand" "r")))]
592 [(set (match_operand:CC 0 "register_operand" "=r")
593 (and:CC (match_operand:CC 1 "register_operand" "%r")
594 (match_operand:CC 2 "register_operand" "r")))]
599 [(set (match_operand:CC 0 "register_operand" "=r")
600 (ior:CC (not:CC (match_operand:CC 1 "register_operand" "r"))
601 (match_operand:CC 2 "register_operand" "r")))]
606 [(set (match_operand:CC 0 "register_operand" "=r")
607 (ior:CC (match_operand:CC 1 "register_operand" "%r")
608 (match_operand:CC 2 "register_operand" "r")))]
613 [(set (match_operand:CC 0 "register_operand" "=r")
614 (rotate:CC (match_operand:CC 1 "register_operand" "r")
615 (match_operand:CC 2 "int5_operand" "")))]
618 [(set_attr "type" "bit")])
620 ;; rotate/and[.c] and rotate/ior[.c]
623 [(set (match_operand:CC 0 "register_operand" "=r")
624 (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
625 (match_operand:CC 2 "int5_operand" ""))
626 (match_operand:CC 3 "register_operand" "r")))
627 (clobber (match_operand:CC 4 "register_operand" "=r"))]
630 (rotate:CC (match_dup 1) (match_dup 2)))
632 (ior:CC (match_dup 4) (match_dup 3)))]
636 [(set (match_operand:CC 0 "register_operand" "=r")
637 (ior:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
638 (match_operand:CC 2 "int5_operand" ""))
639 (match_operand:CC 3 "register_operand" "r")))
640 (clobber (match_scratch:CC 4 "=r"))]
645 [(set (match_operand:CC 0 "register_operand" "=r")
646 (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
647 (match_operand:CC 2 "int5_operand" "")))
648 (match_operand:CC 3 "register_operand" "r")))
649 (clobber (match_operand:CC 4 "register_operand" "=r"))]
652 (rotate:CC (match_dup 1) (match_dup 2)))
654 (ior:CC (not:CC (match_dup 4)) (match_dup 3)))]
658 [(set (match_operand:CC 0 "register_operand" "=r")
659 (ior:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
660 (match_operand:CC 2 "int5_operand" "")))
661 (match_operand:CC 3 "register_operand" "r")))
662 (clobber (match_scratch:CC 4 "=r"))]
667 [(set (match_operand:CC 0 "register_operand" "=r")
668 (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
669 (match_operand:CC 2 "int5_operand" ""))
670 (match_operand:CC 3 "register_operand" "r")))
671 (clobber (match_operand:CC 4 "register_operand" "=r"))]
674 (rotate:CC (match_dup 1) (match_dup 2)))
676 (and:CC (match_dup 4) (match_dup 3)))]
680 [(set (match_operand:CC 0 "register_operand" "=r")
681 (and:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
682 (match_operand:CC 2 "int5_operand" ""))
683 (match_operand:CC 3 "register_operand" "r")))
684 (clobber (match_scratch:CC 4 "=r"))]
689 [(set (match_operand:CC 0 "register_operand" "=r")
690 (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
691 (match_operand:CC 2 "int5_operand" "")))
692 (match_operand:CC 3 "register_operand" "r")))
693 (clobber (match_operand:CC 4 "register_operand" "=r"))]
696 (rotate:CC (match_dup 1) (match_dup 2)))
698 (and:CC (not:CC (match_dup 4)) (match_dup 3)))]
702 [(set (match_operand:CC 0 "register_operand" "=r")
703 (and:CC (not:CC (rotate:CC (match_operand:CC 1 "register_operand" "r")
704 (match_operand:CC 2 "int5_operand" "")))
705 (match_operand:CC 3 "register_operand" "r")))
706 (clobber (match_scratch:CC 4 "=r"))]
710 ;; Recognize bcnd instructions for integer values. This is distinguished
711 ;; from a conditional branch instruction (below) with SImode instead of
717 (match_operator 0 "relop_no_unsigned"
718 [(match_operand:SI 1 "register_operand" "r")
720 (match_operand 2 "pc_or_label_ref" "")
721 (match_operand 3 "pc_or_label_ref" "")))]
723 "bcnd%. %R3%B0,%1,%P2%P3"
724 [(set_attr "type" "branch")])
726 ;; Recognize tests for sign and zero.
731 (match_operator 0 "equality_op"
732 [(match_operand:SI 1 "register_operand" "r")
733 (const_int -2147483648)])
734 (match_operand 2 "pc_or_label_ref" "")
735 (match_operand 3 "pc_or_label_ref" "")))]
737 "bcnd%. %R3%E0,%1,%P2%P3"
738 [(set_attr "type" "branch")])
743 (match_operator 0 "equality_op"
745 (match_operand:SI 1 "register_operand" "r")
749 (match_operand 2 "pc_or_label_ref" "")
750 (match_operand 3 "pc_or_label_ref" "")))]
752 "bcnd%. %R3%D0,%1,%P2%P3"
753 [(set_attr "type" "branch")])
755 ;; Recognize bcnd instructions for double integer values
760 (match_operator 0 "relop_no_unsigned"
762 (match_operand:SI 1 "register_operand" "r"))
764 (match_operand 2 "pc_or_label_ref" "")
765 (match_operand 3 "pc_or_label_ref" "")))]
767 "bcnd%. %R3%B0,%1,%P2%P3"
768 [(set_attr "type" "branch")])
773 (match_operator 0 "equality_op"
775 (match_operand:SI 1 "register_operand" "r"))
777 (match_operand 2 "pc_or_label_ref" "")
778 (match_operand 3 "pc_or_label_ref" "")))]
780 "bcnd%. %R3%B0,%1,%P2%P3"
781 [(set_attr "type" "branch")])
783 ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs
789 ; (match_operator 0 "relop_no_unsigned"
790 ; [(match_operand:DI 1 "register_operand" "r")
792 ; (match_operand 2 "pc_or_label_ref" "")
793 ; (match_operand 3 "pc_or_label_ref" "")))]
797 ; switch (GET_CODE (operands[0]))
801 ; /* I'm not sure if it's safe to use .n here. */
802 ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
805 ; return \"bcnd%. %R3%B0,%1,%P2%P3\";
808 ; rtx op2 = operands[2];
809 ; operands[2] = operands[3];
813 ; if (GET_CODE (operands[3]) == LABEL_REF)
816 ; operands[2] = gen_label_rtx ();
817 ; label_num = XINT (operands[2], 3);
819 ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
820 ; output_label (label_num);
824 ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
828 ;; Recognize bcnd instructions for single precision float values
829 ;; Exclude relational operations as they must signal NaNs.
831 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
836 (match_operator 0 "equality_op"
838 (match_operand:SF 1 "register_operand" "r"))
840 (match_operand 2 "pc_or_label_ref" "")
841 (match_operand 3 "pc_or_label_ref" "")))]
843 "bcnd%. %R3%D0,%1,%P2%P3"
844 [(set_attr "type" "branch")])
849 (match_operator 0 "equality_op"
850 [(match_operand:SF 1 "register_operand" "r")
852 (match_operand 2 "pc_or_label_ref" "")
853 (match_operand 3 "pc_or_label_ref" "")))]
855 "bcnd%. %R3%D0,%1,%P2%P3"
856 [(set_attr "type" "branch")])
858 ;; Recognize bcnd instructions for double precision float values
859 ;; Exclude relational operations as they must signal NaNs.
864 (match_operator 0 "equality_op"
865 [(match_operand:DF 1 "register_operand" "r")
867 (match_operand 2 "pc_or_label_ref" "")
868 (match_operand 3 "pc_or_label_ref" "")))]
874 if (GET_CODE (operands[0]) == NE)
876 rtx op2 = operands[2];
877 operands[2] = operands[3];
880 if (GET_CODE (operands[3]) == LABEL_REF)
881 return \"bcnd%. 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
883 operands[3] = gen_label_rtx ();
884 label_num = XINT (operands[3], 3);
885 output_asm_insn (\"bcnd%. 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
886 output_label (label_num);
889 [(set_attr "type" "branch")])
891 ;; Recognize bb0 and bb1 instructions. These use two unusual template
892 ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF
893 ;; otherwise it outputs a 0. It then may print ".n" if the delay slot
894 ;; is used. %Px does noting if `x' is PC and outputs the operand if `x'
900 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
902 (match_operand:SI 1 "int5_operand" ""))
904 (match_operand 2 "pc_or_label_ref" "")
905 (match_operand 3 "pc_or_label_ref" "")))]
907 "bb%L2 (31-%1),%0,%P2%P3"
908 [(set_attr "type" "branch")])
913 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
915 (match_operand:SI 1 "int5_operand" ""))
917 (match_operand 2 "pc_or_label_ref" "")
918 (match_operand 3 "pc_or_label_ref" "")))]
920 "bb%L3 (31-%1),%0,%P2%P3"
921 [(set_attr "type" "branch")])
926 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
928 (match_operand:SI 1 "int5_operand" ""))
930 (match_operand 2 "pc_or_label_ref" "")
931 (match_operand 3 "pc_or_label_ref" "")))]
933 "bb%L2 (31-%1),%0,%P2%P3"
934 [(set_attr "type" "branch")])
939 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
941 (match_operand:SI 1 "int5_operand" ""))
943 (match_operand 2 "pc_or_label_ref" "")
944 (match_operand 3 "pc_or_label_ref" "")))]
946 "bb%L3 (31-%1),%0,%P2%P3"
947 [(set_attr "type" "branch")])
952 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
953 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
955 (match_operand 2 "pc_or_label_ref" "")
956 (match_operand 3 "pc_or_label_ref" "")))]
957 "(GET_CODE (operands[0]) == CONST_INT)
958 != (GET_CODE (operands[1]) == CONST_INT)"
959 "bb%L3 %p1,%0,%P2%P3"
960 [(set_attr "type" "branch")])
965 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
966 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
968 (match_operand 2 "pc_or_label_ref" "")
969 (match_operand 3 "pc_or_label_ref" "")))]
970 "(GET_CODE (operands[0]) == CONST_INT)
971 != (GET_CODE (operands[1]) == CONST_INT)"
972 "bb%L2 %p1,%0,%P2%P3"
973 [(set_attr "type" "branch")])
975 ;; The comparison operations store the comparison into a register and
976 ;; record that register. The following Bxx or Sxx insn uses that
977 ;; register as an input. To facilitate use of bcnd instead of cmp/bb1,
978 ;; cmpsi records it's operands and produces no code when any operand
979 ;; is constant. In this case, the Bxx insns use gen_bcnd and the
980 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
982 ;; This could also be done for SFmode and DFmode having only beq and bne
983 ;; use gen_bcnd. The others must signal NaNs. It seems though that zero
984 ;; has already been copied into a register.
986 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
987 ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can
988 ;; use bcnd only if an operand is zero.
990 ;; It is necessary to distinguish a register holding condition codes.
991 ;; This is done by context.
993 (define_expand "test"
995 (compare:CC (match_operand 0 "" "")
996 (match_operand 1 "" "")))]
1000 if (m88k_compare_reg)
1003 if (GET_CODE (operands[0]) == CONST_INT
1004 && ! SMALL_INT (operands[0]))
1005 operands[0] = force_reg (SImode, operands[0]);
1007 if (GET_CODE (operands[1]) == CONST_INT
1008 && ! SMALL_INT (operands[1]))
1009 operands[1] = force_reg (SImode, operands[1]);
1011 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1014 ; @@ The docs say don't do this. It's probably a nop since the insn looks
1015 ; identical to cmpsi against zero. Is there an advantage to providing
1016 ; this, perhaps with a different form?
1018 ;(define_expand "tstsi"
1019 ; [(set (match_dup 1)
1020 ; (compare:CC (match_operand:SI 0 "register_operand" "")
1025 ; m88k_compare_reg = 0;
1026 ; m88k_compare_op0 = operands[0];
1027 ; m88k_compare_op1 = const0_rtx;
1031 (define_expand "cmpsi"
1033 (compare:CC (match_operand:SI 0 "register_operand" "")
1034 (match_operand:SI 1 "arith32_operand" "")))]
1038 if (GET_CODE (operands[0]) == CONST_INT
1039 || GET_CODE (operands[1]) == CONST_INT)
1041 m88k_compare_reg = 0;
1042 m88k_compare_op0 = operands[0];
1043 m88k_compare_op1 = operands[1];
1046 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1049 (define_expand "cmpsf"
1051 (compare:CC (match_operand:SF 0 "register_operand" "")
1052 (match_operand:SF 1 "register_operand" "")))]
1054 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1056 (define_expand "cmpdf"
1058 (compare:CC (match_operand:DF 0 "general_operand" "")
1059 (match_operand:DF 1 "general_operand" "")))]
1063 operands[0] = legitimize_operand (operands[0], DFmode);
1064 operands[1] = legitimize_operand (operands[1], DFmode);
1065 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1068 ; @@ Get back to this later on.
1070 ;(define_insn "cmpdi"
1072 ; (compare:CC (match_operand:DI 0 "register_operand" "r")
1073 ; (match_operand:DI 1 "register_operand" "r")))]
1077 ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1078 ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */
1080 ; cc_status.mdep &= ~ MDEP_LS_MASK;
1082 ; operands[2] = gen_label_rtx ();
1083 ; /* Remember, %! is the condition code register and %@ is the
1084 ; literal synthesis register. */
1086 ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1089 ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1090 ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1091 ; output_label (XINT (operands[2], 3));
1095 ;; The actual compare instructions.
1098 [(set (match_operand:CC 0 "register_operand" "=r")
1099 (compare:CC (match_operand:SI 1 "register_operand" "rO")
1100 (match_operand:SI 2 "arith_operand" "rI")))]
1105 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1106 (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1107 (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1113 fcmp.sss %0,%1,%#x0"
1114 [(set_attr "type" "spcmp")])
1117 [(set (match_operand:CC 0 "register_operand" "=r,r")
1118 (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1120 (match_operand:SF 2 "register_operand" "r,x"))))]
1123 [(set_attr "type" "dpcmp")])
1126 [(set (match_operand:CC 0 "register_operand" "=r,r")
1127 (compare:CC (float_extend:DF
1128 (match_operand:SF 1 "register_operand" "r,x"))
1129 (match_operand:DF 2 "register_operand" "r,x")))]
1132 [(set_attr "type" "dpcmp")])
1135 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1136 (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1137 (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1143 fcmp.sds %0,%1,%#x0"
1144 [(set_attr "type" "dpcmp")])
1146 ;; Store condition code insns. The compare insns set a register
1147 ;; rather than cc0 and record that register for use here. See above
1148 ;; for the special treatment of cmpsi with a constant operand.
1150 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1152 (define_expand "seq"
1153 [(set (match_operand:SI 0 "register_operand" "")
1156 "operands[1] = emit_test (EQ, SImode);")
1158 (define_expand "sne"
1159 [(set (match_operand:SI 0 "register_operand" "")
1162 "operands[1] = emit_test (NE, SImode);")
1164 (define_expand "sgt"
1165 [(set (match_operand:SI 0 "register_operand" "")
1168 "operands[1] = emit_test (GT, SImode);")
1170 (define_expand "sgtu"
1171 [(set (match_operand:SI 0 "register_operand" "")
1174 "operands[1] = emit_test (GTU, SImode);")
1176 (define_expand "slt"
1177 [(set (match_operand:SI 0 "register_operand" "")
1180 "operands[1] = emit_test (LT, SImode);")
1182 (define_expand "sltu"
1183 [(set (match_operand:SI 0 "register_operand" "")
1186 "operands[1] = emit_test (LTU, SImode);")
1188 (define_expand "sge"
1189 [(set (match_operand:SI 0 "register_operand" "")
1192 "operands[1] = emit_test (GE, SImode);")
1194 (define_expand "sgeu"
1195 [(set (match_operand:SI 0 "register_operand" "")
1198 "operands[1] = emit_test (GEU, SImode);")
1200 (define_expand "sle"
1201 [(set (match_operand:SI 0 "register_operand" "")
1204 "operands[1] = emit_test (LE, SImode);")
1206 (define_expand "sleu"
1207 [(set (match_operand:SI 0 "register_operand" "")
1210 "operands[1] = emit_test (LEU, SImode);")
1212 ;; The actual set condition code instruction.
1215 [(set (match_operand:SI 0 "register_operand" "=r")
1216 (match_operator:SI 1 "relop"
1217 [(match_operand:CC 2 "register_operand" "r")
1221 [(set_attr "type" "bit")])
1224 [(set (match_operand:SI 0 "register_operand" "=r")
1226 (match_operator:SI 1 "relop"
1227 [(match_operand:CC 2 "register_operand" "r")
1231 [(set_attr "type" "bit")])
1233 ;; Conditional branch insns. The compare insns set a register
1234 ;; rather than cc0 and record that register for use here. See above
1235 ;; for the special case of cmpsi with a constant operand.
1237 (define_expand "bcnd"
1239 (if_then_else (match_operand 0 "" "")
1240 (label_ref (match_operand 1 "" ""))
1243 "if (m88k_compare_reg) abort ();")
1245 (define_expand "bxx"
1247 (if_then_else (match_operand 0 "" "")
1248 (label_ref (match_operand 1 "" ""))
1251 "if (m88k_compare_reg == 0) abort ();")
1253 (define_expand "beq"
1255 (if_then_else (eq (match_dup 1) (const_int 0))
1256 (label_ref (match_operand 0 "" ""))
1259 "if (m88k_compare_reg == 0)
1261 emit_bcnd (EQ, operands[0]);
1264 operands[1] = m88k_compare_reg;")
1266 (define_expand "bne"
1268 (if_then_else (ne (match_dup 1) (const_int 0))
1269 (label_ref (match_operand 0 "" ""))
1272 "if (m88k_compare_reg == 0)
1274 emit_bcnd (NE, operands[0]);
1277 operands[1] = m88k_compare_reg;")
1279 (define_expand "bgt"
1281 (if_then_else (gt (match_dup 1) (const_int 0))
1282 (label_ref (match_operand 0 "" ""))
1285 "if (m88k_compare_reg == 0)
1287 emit_bcnd (GT, operands[0]);
1290 operands[1] = m88k_compare_reg;")
1292 (define_expand "bgtu"
1294 (if_then_else (gtu (match_dup 1) (const_int 0))
1295 (label_ref (match_operand 0 "" ""))
1298 "if (m88k_compare_reg == 0)
1300 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1303 operands[1] = m88k_compare_reg;")
1305 (define_expand "blt"
1307 (if_then_else (lt (match_dup 1) (const_int 0))
1308 (label_ref (match_operand 0 "" ""))
1311 "if (m88k_compare_reg == 0)
1313 emit_bcnd (LT, operands[0]);
1316 operands[1] = m88k_compare_reg;")
1318 (define_expand "bltu"
1320 (if_then_else (ltu (match_dup 1) (const_int 0))
1321 (label_ref (match_operand 0 "" ""))
1324 "if (m88k_compare_reg == 0)
1326 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1329 operands[1] = m88k_compare_reg;")
1331 (define_expand "bge"
1333 (if_then_else (ge (match_dup 1) (const_int 0))
1334 (label_ref (match_operand 0 "" ""))
1337 "if (m88k_compare_reg == 0)
1339 emit_bcnd (GE, operands[0]);
1342 operands[1] = m88k_compare_reg;")
1344 (define_expand "bgeu"
1346 (if_then_else (geu (match_dup 1) (const_int 0))
1347 (label_ref (match_operand 0 "" ""))
1350 "if (m88k_compare_reg == 0)
1352 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1355 operands[1] = m88k_compare_reg;")
1357 (define_expand "ble"
1359 (if_then_else (le (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1363 "if (m88k_compare_reg == 0)
1365 emit_bcnd (LE, operands[0]);
1368 operands[1] = m88k_compare_reg;")
1370 (define_expand "bleu"
1372 (if_then_else (leu (match_dup 1) (const_int 0))
1373 (label_ref (match_operand 0 "" ""))
1376 "if (m88k_compare_reg == 0)
1378 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1381 operands[1] = m88k_compare_reg;")
1383 ;; The actual conditional branch instruction (both directions). This
1384 ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code
1385 ;; for the immediately following condition and reverses the condition iff
1386 ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs
1387 ;; the operand if `x' is a LABEL_REF.
1390 [(set (pc) (if_then_else
1391 (match_operator 0 "relop"
1392 [(match_operand:CC 1 "register_operand" "r")
1394 (match_operand 2 "pc_or_label_ref" "")
1395 (match_operand 3 "pc_or_label_ref" "")))]
1399 if (mostly_false_jump (insn, operands[0]))
1400 return \"bb0%. %R2%C0,%1,%P2%P3\";
1402 return \"bb1%. %R3%C0,%1,%P2%P3\";
1404 [(set_attr "type" "branch")])
1406 ;; Branch conditional on scc values. These arise from manipulations on
1407 ;; compare words above.
1412 (ne (match_operator 0 "relop"
1413 [(match_operand:CC 1 "register_operand" "r")
1416 (match_operand 2 "pc_or_label_ref" "")
1417 (match_operand 3 "pc_or_label_ref" "")))]
1419 "bb1%. %R3%C0,%1,%P2%P3"
1420 [(set_attr "type" "branch")])
1425 (eq (match_operator 0 "relop"
1426 [(match_operand:CC 1 "register_operand" "r")
1429 (match_operand 2 "pc_or_label_ref" "")
1430 (match_operand 3 "pc_or_label_ref" "")))]
1432 "bb0%. %R3%C0,%1,%P2%P3"
1433 [(set_attr "type" "branch")])
1435 (define_insn "locate1"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1439 "or.u %0,%#r0,%#hi16(%1#abdiff)")
1441 (define_insn "locate2"
1442 [(parallel [(set (reg:SI 1) (pc))
1443 (set (match_operand:SI 0 "register_operand" "=r")
1444 (lo_sum:SI (match_dup 0)
1446 [(label_ref (match_operand 1 "" ""))] 0)))])]
1448 "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1449 [(set_attr "length" "2")])
1451 ;; SImode move instructions
1453 (define_expand "movsi"
1454 [(set (match_operand:SI 0 "general_operand" "")
1455 (match_operand:SI 1 "general_operand" ""))]
1459 if (emit_move_sequence (operands, SImode))
1464 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1465 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1466 "(register_operand (operands[0], SImode)
1467 || register_operand (operands[1], SImode)
1468 || operands[1] == const0_rtx)"
1480 [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1483 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1484 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1491 or.u %0,%#r0,%X1\;or %0,%0,%x1"
1492 [(set_attr "type" "arith,arith,arith,bit,marith")])
1494 ;; @@ Why the constraint "in"? Doesn't `i' include `n'?
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1498 (match_operand:SI 2 "immediate_operand" "in")))]
1500 "or %0,%1,%#lo16(%g2)")
1503 [(set (match_operand:SI 0 "register_operand" "=r")
1504 (high:SI (match_operand 1 "" "")))]
1506 "or.u %0,%#r0,%#hi16(%g1)")
1508 ;; HImode move instructions
1510 (define_expand "movhi"
1511 [(set (match_operand:HI 0 "general_operand" "")
1512 (match_operand:HI 1 "general_operand" ""))]
1516 if (emit_move_sequence (operands, HImode))
1521 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1522 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1523 "(register_operand (operands[0], HImode)
1524 || register_operand (operands[1], HImode)
1525 || operands[1] == const0_rtx)"
1531 [(set_attr "type" "arith,load,store,arith")])
1534 [(set (match_operand:HI 0 "register_operand" "=r")
1535 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1536 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1538 "or %0,%1,%#lo16(%2)")
1540 ;; QImode move instructions
1542 (define_expand "movqi"
1543 [(set (match_operand:QI 0 "general_operand" "")
1544 (match_operand:QI 1 "general_operand" ""))]
1548 if (emit_move_sequence (operands, QImode))
1553 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1554 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1555 "(register_operand (operands[0], QImode)
1556 || register_operand (operands[1], QImode)
1557 || operands[1] == const0_rtx)"
1563 [(set_attr "type" "arith,load,store,arith")])
1566 [(set (match_operand:QI 0 "register_operand" "=r")
1567 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1568 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1570 "or %0,%1,%#lo16(%2)")
1572 ;; DImode move instructions
1574 (define_expand "movdi"
1575 [(set (match_operand:DI 0 "general_operand" "")
1576 (match_operand:DI 1 "general_operand" ""))]
1580 if (emit_move_sequence (operands, DImode))
1585 [(set (match_operand:DI 0 "register_operand" "=r,x")
1589 or %0,%#r0,0\;or %d0,%#r0,0
1591 [(set_attr "type" "marith,mov")])
1594 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1595 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1598 or %0,%#r0,%1\;or %d0,%#r0,%d1
1606 [(set_attr "type" "marith,load,store,mov,mov,mov,load,store")])
1609 [(set (match_operand:DI 0 "register_operand" "=r")
1610 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1611 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1613 "or %0,%1,%#lo16(%2)")
1616 [(set (match_operand:DI 0 "register_operand" "=r")
1617 (match_operand:DI 1 "immediate_operand" "n"))]
1619 "* return output_load_const_dimode (operands);"
1620 [(set_attr "type" "marith")
1621 (set_attr "length" "4")]) ; length is 2, 3 or 4.
1623 ;; DFmode move instructions
1625 (define_expand "movdf"
1626 [(set (match_operand:DF 0 "general_operand" "")
1627 (match_operand:DF 1 "general_operand" ""))]
1631 if (emit_move_sequence (operands, DFmode))
1635 ;; @@ This pattern is incomplete and doesn't appear necessary.
1637 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1638 ;; to be reloaded by putting the constant into memory.
1639 ;; It must come before the more general movdf pattern.
1642 ; [(set (match_operand:DF 0 "general_operand" "=r,o")
1643 ; (match_operand:DF 1 "" "G,G"))]
1644 ; "GET_CODE (operands[1]) == CONST_DOUBLE"
1647 ; switch (which_alternative)
1650 ; return \"or %0,%#r0,0\;or %d0,%#r0,0\";
1652 ; operands[1] = adj_offsettable_operand (operands[0], 4);
1653 ; return \"st %#r0,%0\;st %#r0,%1\";
1658 [(set (match_operand:DF 0 "register_operand" "=r,x")
1662 or %0,%#r0,0\;or %d0,%#r0,0
1664 [(set_attr "type" "marith,mov")])
1667 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
1668 (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
1671 or %0,%#r0,%1\;or %d0,%#r0,%d1
1679 [(set_attr "type" "marith,load,store,mov,mov,mov,load,store")])
1682 [(set (match_operand:DF 0 "register_operand" "=r")
1683 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1684 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1686 "or %0,%1,%#lo16(%2)")
1689 [(set (match_operand:DF 0 "register_operand" "=r")
1690 (match_operand:DF 1 "immediate_operand" "F"))]
1692 "* return output_load_const_double (operands);"
1693 [(set_attr "type" "marith")
1694 (set_attr "length" "4")]) ; length is 2, 3, or 4.
1696 ;; SFmode move instructions
1698 (define_expand "movsf"
1699 [(set (match_operand:SF 0 "general_operand" "")
1700 (match_operand:SF 1 "general_operand" ""))]
1704 if (emit_move_sequence (operands, SFmode))
1708 ;; @@ What happens to fconst0_rtx?
1710 [(set (match_operand:SF 0 "register_operand" "=r,x")
1716 [(set_attr "type" "arith,mov")])
1719 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
1720 (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
1731 [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
1734 [(set (match_operand:SF 0 "register_operand" "=r")
1735 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1736 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1738 "or %0,%1,%#lo16(%2)")
1741 [(set (match_operand:SF 0 "register_operand" "=r")
1742 (match_operand:SF 1 "immediate_operand" "F"))]
1743 "operands[1] != const0_rtx"
1744 "* return output_load_const_float (operands);"
1745 [(set_attr "type" "marith")]) ; length is 1 or 2.
1747 ;; String/block move insn. See m88k.c for details.
1749 (define_expand "movstrsi"
1750 [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1751 (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1752 (use (match_operand:SI 2 "arith32_operand" ""))
1753 (use (match_operand:SI 3 "immediate_operand" ""))])]
1757 rtx dest_mem = operands[0];
1758 rtx src_mem = operands[1];
1759 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
1760 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
1761 expand_block_move (dest_mem, src_mem, operands);
1765 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
1766 ;; operand 0 is the function name
1767 ;; operand 1 is the destination pointer
1768 ;; operand 2 is the source pointer
1769 ;; operand 3 is the offset for the source and destination pointers
1770 ;; operand 4 is the first value to be loaded
1771 ;; operand 5 is the register to hold the value (r4 or r5)
1773 (define_expand "call_block_move"
1774 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
1775 (match_operand:SI 3 "immediate_operand" "")))
1776 (set (match_operand 5 "register_operand" "")
1777 (match_operand 4 "memory_operand" ""))
1778 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
1783 (parallel [(call (mem:SI (match_operand 0 "" ""))
1785 (clobber (reg:SI 1))])]
1789 ;; Call a looping block move library function (e.g. __movstrSI64n68).
1790 ;; operands 0-5 as in the non-looping interface
1791 ;; operand 6 is the loop count
1793 (define_expand "call_block_move_loop"
1794 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
1795 (match_operand:SI 3 "immediate_operand" "")))
1796 (set (match_operand:SI 5 "register_operand" "")
1797 (match_operand:SI 4 "memory_operand" ""))
1798 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
1800 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
1805 (parallel [(call (mem:SI (match_operand 0 "" ""))
1807 (clobber (reg:SI 1))])]
1811 ;;- zero extension instructions
1813 (define_expand "zero_extendhisi2"
1814 [(set (match_operand:SI 0 "register_operand" "")
1815 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1819 if (GET_CODE (operands[1]) == MEM
1820 && symbolic_address_p (XEXP (operands[1], 0)))
1822 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1826 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1827 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
1828 "GET_CODE (operands[1]) != CONST_INT"
1833 [(set_attr "type" "arith,arith,load")])
1835 (define_expand "zero_extendqihi2"
1836 [(set (match_operand:HI 0 "register_operand" "")
1837 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1841 if (GET_CODE (operands[1]) == MEM
1842 && symbolic_address_p (XEXP (operands[1], 0)))
1844 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1848 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
1849 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
1850 "GET_CODE (operands[1]) != CONST_INT"
1855 [(set_attr "type" "arith,arith,load")])
1857 (define_expand "zero_extendqisi2"
1858 [(set (match_operand:SI 0 "register_operand" "")
1859 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1863 if (GET_CODE (operands[1]) == MEM
1864 && symbolic_address_p (XEXP (operands[1], 0)))
1867 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1868 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1869 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
1875 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1876 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
1877 "GET_CODE (operands[1]) != CONST_INT"
1882 [(set_attr "type" "arith,arith,load")])
1884 ;;- sign extension instructions
1886 (define_expand "extendsidi2"
1887 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
1888 (match_operand:SI 1 "general_operand" "g"))
1889 (set (subreg:SI (match_dup 0) 0)
1890 (ashiftrt:SI (subreg:SI (match_dup 0) 1)
1895 (define_expand "extendhisi2"
1896 [(set (match_operand:SI 0 "register_operand" "")
1897 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1901 if (GET_CODE (operands[1]) == MEM
1902 && symbolic_address_p (XEXP (operands[1], 0)))
1904 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1908 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1909 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
1910 "GET_CODE (operands[1]) != CONST_INT"
1916 [(set_attr "type" "bit,arith,arith,load")])
1918 (define_expand "extendqihi2"
1919 [(set (match_operand:HI 0 "register_operand" "")
1920 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1924 if (GET_CODE (operands[1]) == MEM
1925 && symbolic_address_p (XEXP (operands[1], 0)))
1927 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1931 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
1932 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
1933 "GET_CODE (operands[1]) != CONST_INT"
1939 [(set_attr "type" "bit,arith,arith,load")])
1941 (define_expand "extendqisi2"
1942 [(set (match_operand:SI 0 "register_operand" "")
1943 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1947 if (GET_CODE (operands[1]) == MEM
1948 && symbolic_address_p (XEXP (operands[1], 0)))
1950 = legitimize_address (flag_pic, operands[1], gen_reg_rtx (Pmode));
1954 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1955 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
1956 "GET_CODE (operands[1]) != CONST_INT"
1962 [(set_attr "type" "bit,arith,arith,load")])
1964 ;; Conversions between float and double.
1966 ;; The fadd instruction does not conform to IEEE 754 when used to
1967 ;; convert between float and double. In particular, the sign of -0 is
1968 ;; not preserved. Interestingly, fsub does conform.
1970 (define_expand "extendsfdf2"
1971 [(set (match_operand:DF 0 "register_operand" "=r")
1972 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
1977 [(set (match_operand:DF 0 "register_operand" "=r")
1978 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
1980 "fsub.dss %0,%1,%#r0"
1981 [(set_attr "type" "spadd")])
1984 [(set (match_operand:DF 0 "register_operand" "=r,x")
1985 (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
1988 [(set_attr "type" "spadd")])
1990 (define_expand "truncdfsf2"
1991 [(set (match_operand:SF 0 "register_operand" "=r")
1992 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
1997 [(set (match_operand:SF 0 "register_operand" "=r")
1998 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2000 "fsub.sds %0,%1,%#r0"
2001 [(set_attr "type" "dpadd")])
2004 [(set (match_operand:SF 0 "register_operand" "=r,x")
2005 (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2008 [(set_attr "type" "dpadd")])
2010 ;; Conversions between floating point and integer
2012 (define_insn "floatsidf2"
2013 [(set (match_operand:DF 0 "register_operand" "=r,x")
2014 (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2017 [(set_attr "type" "spadd,dpadd")])
2019 (define_insn "floatsisf2"
2020 [(set (match_operand:SF 0 "register_operand" "=r,x")
2021 (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2024 [(set_attr "type" "spadd,spadd")])
2026 (define_insn "fix_truncdfsi2"
2027 [(set (match_operand:SI 0 "register_operand" "=r,x")
2028 (fix:SI (match_operand:DF 1 "register_operand" "r,r")))]
2031 [(set_attr "type" "dpadd,dpadd")])
2033 (define_insn "fix_truncsfsi2"
2034 [(set (match_operand:SI 0 "register_operand" "=r,x")
2035 (fix:SI (match_operand:SF 1 "register_operand" "r,r")))]
2038 [(set_attr "type" "spadd,dpadd")])
2041 ;;- arithmetic instructions
2042 ;;- add instructions
2044 (define_insn "addsi3"
2045 [(set (match_operand:SI 0 "register_operand" "=r,r")
2046 (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2047 (match_operand:SI 2 "add_operand" "rI,J")))]
2053 ;; In unusual contexts, an add of a large value is generated (case statements
2054 ;; for example). In these contexts, it is sufficient to accept only those
2055 ;; cases where the two registers are different.
2058 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2059 (plus:SI (match_operand:SI 1 "arith32_operand" "%r,r")
2060 (match_operand:SI 2 "arith32_operand" "r,!n")))]
2066 if (which_alternative == 0)
2067 return \"addu %0,%1,%2\";
2069 xoperands[0] = operands[0];
2070 xoperands[1] = operands[2];
2071 output_asm_insn (output_load_const_int (SImode, xoperands),
2074 return \"addu %0,%1,%0\";
2076 [(set_attr "type" "arith,marith")
2077 (set_attr "length" "1,3")]) ; may be 2 or 3.
2079 ;; patterns for mixed mode floating point.
2080 ;; Do not define patterns that utilize mixed mode arithmetic that result
2081 ;; in narrowing the precision, because it loses accuracy, since the standard
2082 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2084 (define_expand "adddf3"
2085 [(set (match_operand:DF 0 "register_operand" "=r,x")
2086 (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2087 (match_operand:DF 2 "general_operand" "r,x")))]
2091 operands[1] = legitimize_operand (operands[1], DFmode);
2092 operands[2] = legitimize_operand (operands[2], DFmode);
2096 [(set (match_operand:DF 0 "register_operand" "=r,x")
2097 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2098 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2101 [(set_attr "type" "spadd")])
2104 [(set (match_operand:DF 0 "register_operand" "=r,x")
2105 (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2106 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2109 [(set_attr "type" "dpadd")])
2112 [(set (match_operand:DF 0 "register_operand" "=r,x")
2113 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2114 (match_operand:DF 2 "register_operand" "r,x")))]
2117 [(set_attr "type" "dpadd")])
2120 [(set (match_operand:DF 0 "register_operand" "=r,x")
2121 (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2122 (match_operand:DF 2 "register_operand" "r,x")))]
2125 [(set_attr "type" "dpadd")])
2127 (define_insn "addsf3"
2128 [(set (match_operand:SF 0 "register_operand" "=r,x")
2129 (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2130 (match_operand:SF 2 "register_operand" "r,x")))]
2133 [(set_attr "type" "spadd")])
2136 [(set (match_operand:DI 0 "register_operand" "=r")
2137 (plus:DI (match_operand:DI 1 "register_operand" "r")
2139 (match_operand:SI 2 "register_operand" "r"))))
2140 (clobber (reg:CC 0))]
2142 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2143 [(set_attr "type" "marith")])
2146 [(set (match_operand:DI 0 "register_operand" "=r")
2147 (plus:DI (zero_extend:DI
2148 (match_operand:SI 1 "register_operand" "r"))
2149 (match_operand:DI 2 "register_operand" "r")))
2150 (clobber (reg:CC 0))]
2152 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2153 [(set_attr "type" "marith")])
2155 (define_insn "adddi3"
2156 [(set (match_operand:DI 0 "register_operand" "=r")
2157 (plus:DI (match_operand:DI 1 "register_operand" "%r")
2158 (match_operand:DI 2 "register_operand" "r")))
2159 (clobber (reg:CC 0))]
2161 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2162 [(set_attr "type" "marith")])
2164 ;; Add with carry insns.
2167 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2168 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2169 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2171 (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2173 "addu.co %r0,%r1,%r2")
2176 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2177 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2180 "addu.co %#r0,%r0,%r1")
2183 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2184 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2185 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2188 "addu.ci %r0,%r1,%r2")
2190 ;;- subtract instructions
2192 (define_insn "subsi3"
2193 [(set (match_operand:SI 0 "register_operand" "=r")
2194 (minus:SI (match_operand:SI 1 "register_operand" "r")
2195 (match_operand:SI 2 "arith32_operand" "rI")))]
2199 ;; patterns for mixed mode floating point
2200 ;; Do not define patterns that utilize mixed mode arithmetic that result
2201 ;; in narrowing the precision, because it loses accuracy, since the standard
2202 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2204 (define_expand "subdf3"
2205 [(set (match_operand:DF 0 "register_operand" "=r,x")
2206 (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2207 (match_operand:DF 2 "general_operand" "r,x")))]
2211 operands[1] = legitimize_operand (operands[1], DFmode);
2212 operands[2] = legitimize_operand (operands[2], DFmode);
2216 [(set (match_operand:DF 0 "register_operand" "=r,x")
2217 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2218 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2221 [(set_attr "type" "spadd")])
2224 [(set (match_operand:DF 0 "register_operand" "=r,x")
2225 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2226 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2229 [(set_attr "type" "dpadd")])
2232 [(set (match_operand:DF 0 "register_operand" "=r,x")
2233 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2234 (match_operand:DF 2 "register_operand" "r,x")))]
2237 [(set_attr "type" "dpadd")])
2240 [(set (match_operand:DF 0 "register_operand" "=r,x")
2241 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2242 (match_operand:DF 2 "register_operand" "r,x")))]
2245 [(set_attr "type" "dpadd")])
2247 (define_insn "subsf3"
2248 [(set (match_operand:SF 0 "register_operand" "=r,x")
2249 (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2250 (match_operand:SF 2 "register_operand" "r,x")))]
2253 [(set_attr "type" "spadd")])
2256 [(set (match_operand:DI 0 "register_operand" "=r")
2257 (minus:DI (match_operand:DI 1 "register_operand" "r")
2259 (match_operand:SI 2 "register_operand" "r"))))
2260 (clobber (reg:CC 0))]
2262 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2263 [(set_attr "type" "marith")])
2266 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (minus:DI (zero_extend:DI
2268 (match_operand:SI 1 "register_operand" "r"))
2269 (match_operand:DI 2 "register_operand" "r")))
2270 (clobber (reg:CC 0))]
2272 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2273 [(set_attr "type" "marith")])
2275 (define_insn "subdi3"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2277 (minus:DI (match_operand:DI 1 "register_operand" "r")
2278 (match_operand:DI 2 "register_operand" "r")))
2279 (clobber (reg:CC 0))]
2281 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2282 [(set_attr "type" "marith")])
2284 ;; Subtract with carry insns.
2287 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2288 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2289 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2291 (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2293 "subu.co %r0,%r1,%r2")
2296 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2297 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2300 "subu.co %#r0,%r0,%r1")
2303 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2304 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2305 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2308 "subu.ci %r0,%r1,%r2")
2310 ;;- multiply instructions
2312 ;; There is an unfounded silicon eratta for E.1 requiring that an
2313 ;; immediate constant value in div/divu/mul instructions be less than
2314 ;; 0x800. This is no longer provided for.
2316 (define_insn "mulsi3"
2317 [(set (match_operand:SI 0 "register_operand" "=r")
2318 (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2319 (match_operand:SI 2 "arith32_operand" "rI")))]
2322 [(set_attr "type" "imul")])
2324 (define_insn "umulsidi3"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2326 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2327 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2330 [(set_attr "type" "imul")])
2332 ;; patterns for mixed mode floating point
2333 ;; Do not define patterns that utilize mixed mode arithmetic that result
2334 ;; in narrowing the precision, because it loses accuracy, since the standard
2335 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2337 (define_expand "muldf3"
2338 [(set (match_operand:DF 0 "register_operand" "=r,x")
2339 (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2340 (match_operand:DF 2 "general_operand" "r,x")))]
2344 operands[1] = legitimize_operand (operands[1], DFmode);
2345 operands[2] = legitimize_operand (operands[2], DFmode);
2349 [(set (match_operand:DF 0 "register_operand" "=r,x")
2350 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2351 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2354 [(set_attr "type" "spmul")])
2357 [(set (match_operand:DF 0 "register_operand" "=r,x")
2358 (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2359 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2362 [(set_attr "type" "spmul")])
2365 [(set (match_operand:DF 0 "register_operand" "=r,x")
2366 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2367 (match_operand:DF 2 "register_operand" "r,x")))]
2370 [(set_attr "type" "spmul")])
2373 [(set (match_operand:DF 0 "register_operand" "=r,x")
2374 (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2375 (match_operand:DF 2 "register_operand" "r,x")))]
2378 [(set_attr "type" "dpmul")])
2380 (define_insn "mulsf3"
2381 [(set (match_operand:SF 0 "register_operand" "=r,x")
2382 (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2383 (match_operand:SF 2 "register_operand" "r,x")))]
2386 [(set_attr "type" "spmul")])
2388 ;;- divide instructions
2390 ;; The 88k div and divu instructions don't reliably trap on
2391 ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The
2392 ;; general scheme for doing divide is to do a 4-way split based on the
2393 ;; sign of the two operand and do the appropriate negates.
2395 ;; The conditional trap instruction is not used as this serializes the
2396 ;; processor. Instead a conditional branch and an unconditional trap
2397 ;; are used, but after the divu. Since the divu takes up to 38 cycles,
2398 ;; the conditional branch is essentially free.
2400 ;; Two target options control how divide is done. One options selects
2401 ;; whether to do the branch and negate scheme instead of using the div
2402 ;; instruction; the other option selects whether to explicitly check
2403 ;; for divide-by-zero or take your chances. If the div instruction is
2404 ;; used, the O/S must complete the operation if the operands are
2405 ;; negative. The O/S will signal an overflow condition if the most
2406 ;; negative number (-214783648) is divided by negative 1.
2408 ;; There is an unfounded silicon eratta for E.1 requiring that an
2409 ;; immediate constant value in div/divu/mul instructions be less than
2410 ;; 0x800. This is no longer provided for.
2412 ;; Division by 0 trap
2413 (define_insn "trap_divide_by_zero"
2414 [(trap_if (const_int 1) 503)]
2417 [(set_attr "type" "weird")])
2419 ;; Conditional division by 0 trap.
2420 (define_expand "tcnd_divide_by_zero"
2422 (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2425 (match_operand 1 "" "")))
2426 (trap_if (const_int 1) 503)]
2430 emit_insn (gen_cmpsi (operands[0], const0_rtx));
2431 emit_jump_insn (gen_bne (operands[1]));
2432 emit_insn (gen_trap_divide_by_zero ());
2437 (define_expand "divsi3"
2438 [(set (match_operand:SI 0 "register_operand" "")
2439 (div:SI (match_operand:SI 1 "arith32_operand" "")
2440 (match_operand:SI 2 "arith32_operand" "")))]
2444 rtx op0 = operands[0];
2445 rtx op1 = operands[1];
2446 rtx op2 = operands[2];
2449 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making
2450 it a runtime (perhaps quite special). */
2452 if (GET_CODE (op1) == CONST_INT)
2453 op1 = force_reg (SImode, op1);
2455 else if (GET_CODE (op2) == CONST_INT
2456 && ! SMALL_INT (operands[2]))
2457 op2 = force_reg (SImode, op2);
2459 if (op2 == const0_rtx)
2461 emit_insn (gen_trap_divide_by_zero ());
2463 emit_insn (gen_dummy (op0));
2469 emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
2470 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2472 rtx label = gen_label_rtx ();
2473 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2475 emit_insn (gen_dummy (op0));
2480 join_label = gen_label_rtx ();
2481 if (GET_CODE (op1) == CONST_INT)
2484 rtx neg_op2 = gen_reg_rtx (SImode);
2485 rtx label1 = gen_label_rtx ();
2487 if (INTVAL (op1) < 0)
2490 op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
2492 op1 = force_reg (SImode, op1);
2494 emit_insn (gen_negsi2 (neg_op2, op2));
2495 emit_insn (gen_cmpsi (op2, const0_rtx));
2496 emit_jump_insn (gen_bgt (label1));
2497 /* constant / 0-or-negative */
2498 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2500 emit_insn (gen_negsi2 (op0, op0));
2502 if (TARGET_CHECK_ZERO_DIV)
2503 emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2506 emit_jump_insn (gen_jump (join_label));
2510 emit_label (label1); /* constant / positive */
2511 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2513 emit_insn (gen_negsi2 (op0, op0));
2516 else if (GET_CODE (op2) == CONST_INT)
2519 rtx neg_op1 = gen_reg_rtx (SImode);
2520 rtx label1 = gen_label_rtx ();
2522 if (INTVAL (op2) < 0)
2525 op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
2527 else if (! SMALL_INT (operands[2]))
2528 op2 = force_reg (SImode, op2);
2530 emit_insn (gen_negsi2 (neg_op1, op1));
2531 emit_insn (gen_cmpsi (op1, const0_rtx));
2532 emit_jump_insn (gen_bge (label1));
2533 /* 0-or-negative / constant */
2534 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2536 emit_insn (gen_negsi2 (op0, op0));
2538 emit_jump_insn (gen_jump (join_label));
2541 emit_label (label1); /* positive / constant */
2542 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2544 emit_insn (gen_negsi2 (op0, op0));
2549 rtx neg_op1 = gen_reg_rtx (SImode);
2550 rtx neg_op2 = gen_reg_rtx (SImode);
2551 rtx label1 = gen_label_rtx ();
2552 rtx label2 = gen_label_rtx ();
2553 rtx label3 = gen_label_rtx ();
2556 emit_insn (gen_negsi2 (neg_op2, op2));
2557 emit_insn (gen_cmpsi (op2, const0_rtx));
2558 emit_jump_insn (gen_bgt (label1));
2560 emit_insn (gen_negsi2 (neg_op1, op1));
2561 emit_insn (gen_cmpsi (op1, const0_rtx));
2562 emit_jump_insn (gen_bge (label2));
2563 /* negative / negative-or-0 */
2564 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
2566 if (TARGET_CHECK_ZERO_DIV)
2568 label4 = gen_label_rtx ();
2569 emit_insn (gen_cmpsi (op2, const0_rtx));
2570 emit_jump_insn (gen_bne (join_label));
2571 emit_label (label4);
2572 emit_insn (gen_trap_divide_by_zero ());
2577 emit_jump_insn (gen_jump (join_label));
2581 emit_label (label2); /* pos.-or-0 / neg.-or-0 */
2582 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2584 if (TARGET_CHECK_ZERO_DIV)
2586 emit_insn (gen_cmpsi (op2, const0_rtx));
2587 emit_jump_insn (gen_beq (label4));
2590 emit_insn (gen_negsi2 (op0, op0));
2591 emit_jump_insn (gen_jump (join_label));
2594 emit_label (label1);
2595 emit_insn (gen_negsi2 (neg_op1, op1));
2596 emit_insn (gen_cmpsi (op1, const0_rtx));
2597 emit_jump_insn (gen_bge (label3));
2598 /* negative / positive */
2599 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2600 emit_insn (gen_negsi2 (op0, op0));
2601 emit_jump_insn (gen_jump (join_label));
2604 emit_label (label3); /* positive-or-0 / positive */
2605 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2608 emit_label (join_label);
2610 emit_insn (gen_dummy (op0));
2615 [(set (match_operand:SI 0 "register_operand" "=r")
2616 (div:SI (match_operand:SI 1 "register_operand" "r")
2617 (match_operand:SI 2 "arith_operand" "rI")))]
2620 [(set_attr "type" "idiv")])
2622 (define_expand "udivsi3"
2623 [(set (match_operand:SI 0 "register_operand" "")
2624 (udiv:SI (match_operand:SI 1 "register_operand" "")
2625 (match_operand:SI 2 "arith32_operand" "")))]
2629 rtx op2 = operands[2];
2631 if (op2 == const0_rtx)
2633 emit_insn (gen_trap_divide_by_zero ());
2635 emit_insn (gen_dummy (operands[0]));
2638 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
2640 rtx label = gen_label_rtx ();
2641 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2642 gen_rtx (UDIV, SImode, operands[1], op2)));
2643 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2645 emit_insn (gen_dummy (operands[0]));
2651 [(set (match_operand:SI 0 "register_operand" "=r")
2652 (udiv:SI (match_operand:SI 1 "register_operand" "r")
2653 (match_operand:SI 2 "arith32_operand" "rI")))]
2654 "operands[2] != const0_rtx"
2656 [(set_attr "type" "idiv")])
2659 [(set (match_operand:SI 0 "register_operand" "=r")
2660 (udiv:SI (match_operand:SI 1 "register_operand" "r")
2664 [(set_attr "type" "weird")])
2666 ;; patterns for mixed mode floating point.
2667 ;; Do not define patterns that utilize mixed mode arithmetic that result
2668 ;; in narrowing the precision, because it loses accuracy, since the standard
2669 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2671 (define_expand "divdf3"
2672 [(set (match_operand:DF 0 "register_operand" "=r,x")
2673 (div:DF (match_operand:DF 1 "general_operand" "r,x")
2674 (match_operand:DF 2 "general_operand" "r,x")))]
2678 operands[1] = legitimize_operand (operands[1], DFmode);
2679 if (real_power_of_2_operand (operands[2]))
2681 union real_extract u;
2682 bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
2683 emit_insn (gen_muldf3 (operands[0], operands[1],
2684 CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
2687 else if (! register_operand (operands[2], DFmode))
2688 operands[2] = force_reg (DFmode, operands[2]);
2692 [(set (match_operand:DF 0 "register_operand" "=r,x")
2693 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2694 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2697 [(set_attr "type" "dpdiv")])
2700 [(set (match_operand:DF 0 "register_operand" "=r,x")
2701 (div:DF (match_operand:DF 1 "register_operand" "r,x")
2702 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2705 [(set_attr "type" "dpdiv")])
2708 [(set (match_operand:DF 0 "register_operand" "=r,x")
2709 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2710 (match_operand:DF 2 "register_operand" "r,x")))]
2713 [(set_attr "type" "dpdiv")])
2715 (define_insn "divsf3"
2716 [(set (match_operand:SF 0 "register_operand" "=r,x")
2717 (div:SF (match_operand:SF 1 "register_operand" "r,x")
2718 (match_operand:SF 2 "register_operand" "r,x")))]
2721 [(set_attr "type" "spdiv")])
2724 [(set (match_operand:DF 0 "register_operand" "=r,x")
2725 (div:DF (match_operand:DF 1 "register_operand" "r,x")
2726 (match_operand:DF 2 "register_operand" "r,x")))]
2729 [(set_attr "type" "dpdiv")])
2731 ;; - remainder instructions, don't define, since the hardware doesn't have any
2732 ;; direct support, and GNU can synthesis them out of div/mul just fine.
2734 ;;- load effective address, must come after add, so that we favor using
2735 ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require
2736 ;; the data unit), and also future 88k chips might not support unscaled
2737 ;; lda instructions.
2740 [(set (match_operand:SI 0 "register_operand" "=r")
2741 (match_operand:SI 1 "address_operand" "p"))]
2742 "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
2746 [(set (match_operand:SI 0 "register_operand" "=r")
2747 (match_operand:HI 1 "address_operand" "p"))]
2750 [(set_attr "type" "loada")])
2753 [(set (match_operand:SI 0 "register_operand" "=r")
2754 (match_operand:SI 1 "address_operand" "p"))]
2757 [(set_attr "type" "loada")])
2760 [(set (match_operand:SI 0 "register_operand" "=r")
2761 (match_operand:DI 1 "address_operand" "p"))]
2764 [(set_attr "type" "loada")])
2767 [(set (match_operand:SI 0 "register_operand" "=r")
2768 (match_operand:SF 1 "address_operand" "p"))]
2771 [(set_attr "type" "loada")])
2774 [(set (match_operand:SI 0 "register_operand" "=r")
2775 (match_operand:DF 1 "address_operand" "p"))]
2778 [(set_attr "type" "loada")])
2780 ;;- and instructions (with complement also)
2782 [(set (match_operand:SI 0 "register_operand" "=r")
2783 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2784 (match_operand:SI 2 "register_operand" "r")))]
2788 ;; If the operation is being performed on a 32-bit constant such that
2789 ;; it cannot be done in one insn, do it in two. We may lose a bit on
2790 ;; CSE in pathological cases, but it seems better doing it this way.
2792 (define_expand "andsi3"
2793 [(set (match_operand:SI 0 "register_operand" "")
2794 (and:SI (match_operand:SI 1 "arith32_operand" "")
2795 (match_operand:SI 2 "arith32_operand" "")))]
2799 if (GET_CODE (operands[2]) == CONST_INT)
2801 int value = INTVAL (operands[2]);
2803 if (! (SMALL_INTVAL (value)
2804 || (value & 0xffff0000) == 0xffff0000
2805 || (value & 0xffff) == 0xffff
2806 || (value & 0xffff) == 0
2807 || integer_ok_for_set (~value)))
2809 emit_insn (gen_andsi3 (operands[0], operands[1],
2810 gen_rtx (CONST_INT, VOIDmode,
2812 operands[1] = operands[0];
2813 operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
2819 [(set (match_operand:SI 0 "register_operand" "=r,r")
2820 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
2821 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
2823 "* return output_and (operands);"
2824 [(set_attr "type" "arith,marith")])
2827 [(set (match_operand:DI 0 "register_operand" "=r")
2828 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2829 (match_operand:DI 2 "register_operand" "r")))]
2831 "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
2832 [(set_attr "type" "marith")])
2834 (define_insn "anddi3"
2835 [(set (match_operand:DI 0 "register_operand" "=r")
2836 (and:DI (match_operand:DI 1 "arith64_operand" "%r")
2837 (match_operand:DI 2 "arith64_operand" "rn")))]
2843 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2844 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2845 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2847 output_asm_insn (output_and (xoperands), xoperands);
2849 operands[0] = operand_subword (operands[0], 0, 0, DImode);
2850 operands[1] = operand_subword (operands[1], 0, 0, DImode);
2851 operands[2] = operand_subword (operands[2], 0, 0, DImode);
2853 return output_and (operands);
2855 [(set_attr "type" "marith")
2856 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2858 ;;- Bit set (inclusive or) instructions (with complement also)
2860 [(set (match_operand:SI 0 "register_operand" "=r")
2861 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2862 (match_operand:SI 2 "register_operand" "r")))]
2866 (define_expand "iorsi3"
2867 [(set (match_operand:SI 0 "register_operand" "")
2868 (ior:SI (match_operand:SI 1 "arith32_operand" "")
2869 (match_operand:SI 2 "arith32_operand" "")))]
2873 if (GET_CODE (operands[2]) == CONST_INT)
2875 int value = INTVAL (operands[2]);
2877 if (! (SMALL_INTVAL (value)
2878 || (value & 0xffff) == 0
2879 || integer_ok_for_set (value)))
2881 emit_insn (gen_iorsi3 (operands[0], operands[1],
2882 gen_rtx (CONST_INT, VOIDmode,
2883 value & 0xffff0000)));
2884 operands[1] = operands[0];
2885 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
2891 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2892 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
2893 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
2899 or.u %0,%1,%X2\;or %0,%0,%x2"
2900 [(set_attr "type" "arith,arith,bit,marith")])
2903 [(set (match_operand:DI 0 "register_operand" "=r")
2904 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2905 (match_operand:DI 2 "register_operand" "r")))]
2907 "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
2908 [(set_attr "type" "marith")])
2910 (define_insn "iordi3"
2911 [(set (match_operand:DI 0 "register_operand" "=r")
2912 (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
2913 (match_operand:DI 2 "arith64_operand" "rn")))]
2919 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2920 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2921 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2923 output_asm_insn (output_ior (xoperands), xoperands);
2925 operands[0] = operand_subword (operands[0], 0, 0, DImode);
2926 operands[1] = operand_subword (operands[1], 0, 0, DImode);
2927 operands[2] = operand_subword (operands[2], 0, 0, DImode);
2929 return output_ior (operands);
2931 [(set_attr "type" "marith")
2932 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2934 ;;- xor instructions (with complement also)
2936 [(set (match_operand:SI 0 "register_operand" "=r")
2937 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
2938 (match_operand:SI 2 "register_operand" "r"))))]
2942 (define_expand "xorsi3"
2943 [(set (match_operand:SI 0 "register_operand" "")
2944 (xor:SI (match_operand:SI 1 "arith32_operand" "")
2945 (match_operand:SI 2 "arith32_operand" "")))]
2949 if (GET_CODE (operands[2]) == CONST_INT)
2951 int value = INTVAL (operands[2]);
2953 if (! (SMALL_INTVAL (value)
2954 || (value & 0xffff) == 0))
2956 emit_insn (gen_xorsi3 (operands[0], operands[1],
2957 gen_rtx (CONST_INT, VOIDmode,
2958 value & 0xffff0000)));
2959 operands[1] = operands[0];
2960 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
2966 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2967 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
2968 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
2973 xor.u %0,%1,%X2\;xor %0,%0,%x2"
2974 [(set_attr "type" "arith,arith,marith")])
2977 [(set (match_operand:DI 0 "register_operand" "=r")
2978 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2979 (match_operand:DI 2 "register_operand" "r"))))]
2981 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
2982 [(set_attr "type" "marith")])
2984 (define_insn "xordi3"
2985 [(set (match_operand:DI 0 "register_operand" "=r")
2986 (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
2987 (match_operand:DI 2 "arith64_operand" "rn")))]
2993 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
2994 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
2995 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
2997 output_asm_insn (output_xor (xoperands), xoperands);
2999 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3000 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3001 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3003 return output_xor (operands);
3005 [(set_attr "type" "marith")
3006 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3008 ;;- ones complement instructions
3009 (define_insn "one_cmplsi2"
3010 [(set (match_operand:SI 0 "register_operand" "=r")
3011 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3015 (define_insn "one_cmpldi2"
3016 [(set (match_operand:DI 0 "register_operand" "=r")
3017 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3019 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3020 [(set_attr "type" "marith")])
3022 ;; Optimized special cases of shifting.
3023 ;; Must precede the general case.
3025 ;; @@ What about HImode shifted by 8?
3028 [(set (match_operand:SI 0 "register_operand" "=r")
3029 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3031 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3033 [(set_attr "type" "load")])
3036 [(set (match_operand:SI 0 "register_operand" "=r")
3037 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3039 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3041 [(set_attr "type" "load")])
3044 [(set (match_operand:SI 0 "register_operand" "=r")
3045 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3047 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3049 [(set_attr "type" "load")])
3052 [(set (match_operand:SI 0 "register_operand" "=r")
3053 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3055 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3057 [(set_attr "type" "load")])
3059 ;;- arithmetic shift instructions.
3061 ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should
3062 ;; be arith32_operand?
3064 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3066 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3067 (match_operand:SI 1 "arith_operand" "rI"))
3071 [(set_attr "type" "weird")])
3073 ;; Just in case the optimizer decides to fold away the test.
3075 [(trap_if (const_int 1) 7)]
3078 [(set_attr "type" "weird")])
3080 (define_expand "ashlsi3"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (ashift:SI (match_operand:SI 1 "register_operand" "")
3083 (match_operand:SI 2 "arith32_operand" "")))]
3087 if (GET_CODE (operands[2]) == CONST_INT)
3089 if ((unsigned) INTVAL (operands[2]) > 31)
3091 if (TARGET_TRAP_LARGE_SHIFT)
3092 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3093 gen_rtx (CONST_INT, VOIDmode, 31)));
3095 emit_move_insn (operands[0], const0_rtx);
3100 else if (TARGET_TRAP_LARGE_SHIFT)
3101 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3103 else if (TARGET_HANDLE_LARGE_SHIFT)
3105 rtx reg = gen_reg_rtx (SImode);
3106 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3107 emit_insn (gen_sleu (reg));
3108 emit_insn (gen_andsi3 (reg, operands[1], reg));
3114 [(set (match_operand:SI 0 "register_operand" "=r,r")
3115 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3116 (match_operand:SI 2 "arith5_operand" "r,n")))]
3121 [(set_attr "type" "bit")])
3123 (define_expand "ashrsi3"
3124 [(set (match_operand:SI 0 "register_operand" "")
3125 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3126 (match_operand:SI 2 "arith32_operand" "")))]
3130 if (GET_CODE (operands[2]) == CONST_INT)
3132 if ((unsigned) INTVAL (operands[2]) > 31)
3134 if (TARGET_TRAP_LARGE_SHIFT)
3136 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3137 gen_rtx (CONST_INT, VOIDmode, 31)));
3141 operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
3145 else if (TARGET_TRAP_LARGE_SHIFT)
3146 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3148 else if (TARGET_HANDLE_LARGE_SHIFT)
3150 rtx reg = gen_reg_rtx (SImode);
3151 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3152 emit_insn (gen_sgtu (reg));
3153 emit_insn (gen_iorsi3 (reg, operands[2], reg));
3159 [(set (match_operand:SI 0 "register_operand" "=r,r")
3160 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3161 (match_operand:SI 2 "arith5_operand" "r,n")))]
3166 [(set_attr "type" "bit")])
3168 ;;- logical shift instructions. Logical shift left becomes arithmetic
3169 ;; shift left. LSHIFT is not normally produced, but is supported.
3171 (define_expand "lshlsi3"
3172 [(set (match_operand:SI 0 "register_operand" "")
3173 (lshift:SI (match_operand:SI 1 "register_operand" "")
3174 (match_operand:SI 2 "arith32_operand" "")))]
3178 emit_insn (gen_ashlsi3 (operands[0], operands[1], operands[2]));
3183 [(set (match_operand:SI 0 "register_operand" "=r,r")
3184 (lshift:SI (match_operand:SI 1 "register_operand" "r,r")
3185 (match_operand:SI 2 "arith5_operand" "r,n")))]
3190 [(set_attr "type" "bit")])
3192 (define_expand "lshrsi3"
3193 [(set (match_operand:SI 0 "register_operand" "")
3194 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3195 (match_operand:SI 2 "arith32_operand" "")))]
3199 if (GET_CODE (operands[2]) == CONST_INT)
3201 if ((unsigned) INTVAL (operands[2]) > 31)
3203 if (TARGET_TRAP_LARGE_SHIFT)
3204 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3205 gen_rtx (CONST_INT, VOIDmode, 31)));
3207 emit_move_insn (operands[0], const0_rtx);
3212 else if (TARGET_TRAP_LARGE_SHIFT)
3213 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3215 else if (TARGET_HANDLE_LARGE_SHIFT)
3217 rtx reg = gen_reg_rtx (SImode);
3218 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3219 emit_insn (gen_sleu (reg));
3220 emit_insn (gen_andsi3 (reg, operands[1], reg));
3226 [(set (match_operand:SI 0 "register_operand" "=r,r")
3227 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3228 (match_operand:SI 2 "arith5_operand" "r,n")))]
3233 [(set_attr "type" "bit")])
3235 ;;- rotate instructions
3237 (define_expand "rotlsi3"
3238 [(set (match_operand:SI 0 "register_operand" "")
3239 (rotatert:SI (match_operand:SI 1 "register_operand" "")
3240 (match_operand:SI 2 "arith32_operand" "")))]
3244 if (GET_CODE (operands[2]) == CONST_INT
3245 && (unsigned) INTVAL (operands[2]) >= 32)
3246 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3247 (32 - INTVAL (operands[2])) % 32);
3250 rtx op = gen_reg_rtx (SImode);
3251 emit_insn (gen_negsi2 (op, operands[2]));
3256 (define_insn "rotrsi3"
3257 [(set (match_operand:SI 0 "register_operand" "=r")
3258 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3259 (match_operand:SI 2 "arith_operand" "rI")))]
3262 [(set_attr "type" "bit")])
3266 ;; The ff1 instruction searches from the most significant bit while ffs
3267 ;; searches from the least significant bit. The bit index and treatment of
3268 ;; zero also differ. This amazing sequence was discovered using the GNU
3271 (define_insn "ffssi2"
3272 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3273 (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3274 (clobber (reg:CC 0))
3275 (clobber (match_scratch:SI 2 "=r,X"))]
3278 subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3279 subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3280 [(set_attr "type" "marith")
3281 (set_attr "length" "4")])
3283 ;; Bit field instructions.
3286 [(set (match_operand:SI 0 "register_operand" "=r")
3287 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3294 [(set (match_operand:SI 0 "register_operand" "=r")
3295 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3296 (match_operand:SI 2 "int5_operand" "")
3297 (match_operand:SI 3 "int5_operand" "")))]
3301 operands[4] = gen_rtx (CONST_INT, SImode,
3302 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3303 return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3305 [(set_attr "type" "bit")])
3308 [(set (match_operand:SI 0 "register_operand" "=r")
3309 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3315 (define_insn "extzv"
3316 [(set (match_operand:SI 0 "register_operand" "=r")
3317 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3318 (match_operand:SI 2 "int5_operand" "")
3319 (match_operand:SI 3 "int5_operand" "")))]
3323 operands[4] = gen_rtx (CONST_INT, SImode,
3324 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3325 return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3327 [(set_attr "type" "bit")])
3330 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3331 (match_operand:SI 1 "int5_operand" "")
3332 (match_operand:SI 2 "int5_operand" ""))
3337 operands[3] = gen_rtx (CONST_INT, SImode,
3338 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3339 return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3341 [(set_attr "type" "bit")])
3344 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3345 (match_operand:SI 1 "int5_operand" "")
3346 (match_operand:SI 2 "int5_operand" ""))
3351 operands[3] = gen_rtx (CONST_INT, SImode,
3352 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3353 return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3355 [(set_attr "type" "bit")])
3358 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3359 (match_operand:SI 1 "int5_operand" "")
3360 (match_operand:SI 2 "int5_operand" ""))
3361 (match_operand:SI 3 "int32_operand" "n"))]
3365 int value = INTVAL (operands[3]);
3367 if (INTVAL (operands[1]) < 32)
3368 value &= (1 << INTVAL (operands[1])) - 1;
3370 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3371 32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3373 value <<= INTVAL (operands[2]);
3374 operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
3376 if (SMALL_INTVAL (value))
3377 return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3378 else if ((value & 0x0000ffff) == 0)
3379 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3381 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3383 [(set_attr "type" "marith")
3384 (set_attr "length" "3")]) ; may be 2 or 3.
3387 (define_insn "negsi2"
3388 [(set (match_operand:SI 0 "register_operand" "=r")
3389 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3394 [(set (match_operand:SF 0 "register_operand" "=r,x")
3395 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3399 fsub.ssd %0,%#x0,%1"
3400 [(set_attr "type" "dpadd")])
3402 (define_insn "negdf2"
3403 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3404 (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3407 xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3409 [(set_attr "type" "marith,arith")])
3411 (define_insn "negsf2"
3412 [(set (match_operand:SF 0 "register_operand" "=r")
3413 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3415 "xor.u %0,%1,0x8000")
3417 ;; absolute value insns for floating-point (integer abs can be done using the
3418 ;; machine-independent sequence).
3420 (define_insn "absdf2"
3421 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3422 (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3425 and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3427 [(set_attr "type" "marith,arith")])
3429 (define_insn "abssf2"
3430 [(set (match_operand:SF 0 "register_operand" "=r")
3431 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3433 "and.u %0,%1,0x7fff")
3435 ;; Subroutines of "casesi".
3437 ;; Operand 0 is index
3438 ;; operand 1 is the minimum bound
3439 ;; operand 2 is the maximum bound - minimum bound + 1
3440 ;; operand 3 is CODE_LABEL for the table;
3441 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3443 (define_expand "casesi"
3444 ;; We don't use these for generating the RTL, but we must describe
3445 ;; the operands here.
3446 [(match_operand:SI 0 "general_operand" "")
3447 (match_operand:SI 1 "immediate_operand" "")
3448 (match_operand:SI 2 "immediate_operand" "")
3449 (match_operand 3 "" "")
3450 (match_operand 4 "" "")]
3454 register rtx index_diff = gen_reg_rtx (SImode);
3455 register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
3456 register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
3459 if (! CASE_VECTOR_INSNS)
3460 /* These instructions are likely to be scheduled and made loop invariant.
3461 This decreases the cost of the dispatch at the expense of the default
3463 base = force_reg (SImode, memory_address_noforce (SImode, label));
3465 /* Compute the index difference and handle the default case. */
3466 emit_insn (gen_addsi3 (index_diff,
3467 force_reg (SImode, operands[0]),
3468 ADD_INT (low) ? low : force_reg (SImode, low)));
3469 emit_insn (gen_cmpsi (index_diff, operands[2]));
3470 /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3471 entry to the table. However, that doesn't seem to win on the m88110. */
3472 emit_jump_insn (gen_bgtu (operands[4]));
3474 if (CASE_VECTOR_INSNS)
3475 /* Call the jump that will branch to the appropriate case. */
3476 emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3478 /* Load the table entry and jump to it. */
3479 emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff));
3481 /* Claim that flow drops into the table so it will be adjacent by not
3482 emitting a barrier. */
3486 (define_expand "casesi_jump"
3487 [(set (match_operand:SI 0 "" "")
3488 (mem:SI (plus:SI (match_operand:SI 1 "" "")
3489 (mult:SI (match_operand:SI 2 "" "")
3491 (set (pc) (match_dup 0))]
3495 ;; The bsr.n instruction is directed to the END of the table. See
3496 ;; ASM_OUTPUT_CASE_END.
3498 (define_insn "casesi_enter"
3499 [(set (pc) (match_operand 0 "" ""))
3500 (use (match_operand:SI 1 "register_operand" "r"))
3501 ;; The USE here is so that at least one jump-insn will refer to the label,
3502 ;; to keep it alive in jump_optimize.
3503 (use (label_ref (match_operand 2 "" "")))
3504 (clobber (reg:SI 1))]
3508 if (flag_delayed_branch)
3509 return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3510 m88k_case_index = REGNO (operands[1]);
3513 [(set_attr "type" "weird")
3514 (set_attr "length" "3")]) ; Including the "jmp r1".
3516 ;;- jump to subroutine
3517 (define_expand "call"
3518 [(parallel [(call (match_operand:SI 0 "" "")
3519 (match_operand 1 "" ""))
3520 (clobber (reg:SI 1))])]
3524 if (GET_CODE (operands[0]) == MEM
3525 && ! call_address_operand (XEXP (operands[0], 0), SImode))
3526 operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
3527 force_reg (Pmode, XEXP (operands[0], 0)));
3531 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3532 (match_operand 1 "" ""))
3533 (clobber (reg:SI 1))])]
3535 "* return output_call (operands, operands[0]);"
3536 [(set_attr "type" "call")])
3538 (define_expand "call_value"
3539 [(parallel [(set (match_operand 0 "register_operand" "")
3540 (call (match_operand:SI 1 "" "")
3541 (match_operand 2 "" "")))
3542 (clobber (reg:SI 1))])]
3546 if (GET_CODE (operands[1]) == MEM
3547 && ! call_address_operand (XEXP (operands[1], 0), SImode))
3548 operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
3549 force_reg (Pmode, XEXP (operands[1], 0)));
3553 [(parallel [(set (match_operand 0 "register_operand" "=r")
3555 (match_operand:SI 1 "call_address_operand" "rQ"))
3556 (match_operand 2 "" "")))
3557 (clobber (reg:SI 1))])]
3559 "* return output_call (operands, operands[1]);"
3560 [(set_attr "type" "call")])
3562 ;; Nop instruction and others
3568 [(set_attr "type" "bit")])
3570 (define_insn "return"
3574 [(set_attr "type" "jump")])
3576 (define_expand "prologue"
3579 "m88k_expand_prologue (); DONE;")
3581 (define_expand "epilogue"
3582 [(set (pc) (reg:SI 1))]
3583 "! null_prologue ()"
3584 "m88k_expand_epilogue ();")
3586 (define_insn "blockage"
3587 [(unspec_volatile [(const_int 0)] 0)]
3590 [(set_attr "length" "0")])
3592 (define_insn "indirect_jump"
3593 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3596 [(set_attr "type" "jump")])
3600 (label_ref (match_operand 0 "" "")))]
3603 [(set_attr "type" "jump")])
3605 ;; This insn is used for some loop tests, typically loops reversed when
3606 ;; strength reduction is used. It is actually created when the instruction
3607 ;; combination phase combines the special loop test. Since this insn
3608 ;; is both a jump insn and has an output, it must deal with it's own
3609 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
3610 ;; to not choose the register alternatives in the event a reload is needed.
3612 (define_insn "decrement_and_branch_until_zero"
3615 (match_operator 0 "relop_no_unsigned"
3616 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
3618 (label_ref (match_operand 2 "" ""))
3621 (plus:SI (match_dup 1)
3622 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
3623 (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
3624 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
3625 "find_reg_note (insn, REG_NONNEG, 0)"
3627 bcnd.n %B0,%1,%2\;addu %1,%1,%3
3628 bcnd.n %B0,%1,%2\;subu %1,%1,%n3
3629 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
3630 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
3631 [(set_attr "type" "weird")
3632 (set_attr "length" "2,2,4,4")])
3634 ;; Special insn to serve as the last insn of a define_expand. This insn
3635 ;; will generate no code.
3637 (define_expand "dummy"
3638 [(set (match_operand 0 "" "") (match_dup 0))]
3642 ;;- Local variables:
3644 ;;- comment-start: ";;- "
3645 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3646 ;;- eval: (modify-syntax-entry ?[ "(]")
3647 ;;- eval: (modify-syntax-entry ?] ")[")
3648 ;;- eval: (modify-syntax-entry ?{ "(}")
3649 ;;- eval: (modify-syntax-entry ?} "){")