1 ;;- Machine description for the Motorola 88000 for GNU C compiler
2 ;; Copyright (C) 1988, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@mcc.com)
4 ;; Additional changes by Michael Meissner (meissner@osf.org)
5 ;; Version 2 port by Tom Wood (twood@pets.sps.mot.com)
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; RCS rev field. This is a NOP, just to get the RCS id into the
29 (define_expand "m88k_rcs_id"
30 [(match_operand:SI 0 "" "")]
32 "{ static char rcs_id[] = \"$What: <@(#) m88k.md,v 1.1.1.2.2.2> $\";
35 ;; Attribute describing the processor. This attribute must match exactly
36 ;; with the processor_type enumeration in m88k.h.
39 (define_attr "cpu" "m88100,m88110,m88000"
40 (const (symbol_ref "m88k_cpu")))
42 ; Type of each instruction. Default is arithmetic.
43 ; I'd like to write the list as this, but genattrtab won't accept it.
45 ; "branch,jump,call, ; flow-control instructions
46 ; load,store,loadd,loada, ; data unit instructions
47 ; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
48 ; spmul,dpmul,imul, ; FPU multiply instructions
49 ; arith,bit,mov ; integer unit instructions
50 ; marith,weird" ; multi-word instructions
52 ; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
54 "branch,jump,call,load,store,loadd,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,weird"
55 (const_string "arith"))
57 (define_attr "fpu" "yes,no"
59 (eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv")
60 (const_string "yes") (const_string "no")))
62 ; Length in # of instructions of each insn. The values are not exact, but
64 (define_attr "length" ""
65 (cond [(eq_attr "type" "marith,weird,branch")
69 ; Describe a user's asm statement.
70 (define_asm_attributes
71 [(set_attr "type" "weird")])
73 ; Define the delay slot requirements for branches and calls.
74 ; The m88100 annuls instructions if a conditional branch is taken.
75 ; For insns of TYPE_BRANCH that are multi-word instructions, the
76 ; delay slot applies to the first instruction.
78 ; @@ For the moment, reorg.c requires that the delay slot of a branch not
79 ; be a call or branch.
81 (define_delay (eq_attr "type" "branch,jump")
84 (eq_attr "type" "!branch,jump,call,marith,weird") ; required.
85 (eq_attr "type" "!load,loadd")) ; issue as-soon-as-possible.
86 (eq_attr "fpu" "no")) ; issue as-soon-as-possible.
87 (eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
89 ; output_call supports an unconditional branch in the delay slot of
90 ; a call. (@@ Support for this case is expected in reorg.c soon.)
92 (define_delay (eq_attr "type" "call")
93 [(eq_attr "type" "!branch,call,marith,weird") ; required.
96 ; An abstract block diagram of the function units for the m88100.
103 ; ,----------'| | `----------------------.
105 ; load | store | | arith | | |
106 ; | | | +-v-v-+ | dp source
108 ; store | | | div +-v-v-+
109 ; ,------. | | | ,-----. ,-----------' `-----------.
111 ; | +--v---v--+ ,---' | | +-v-v---+ +---v---+
112 ; | | stage 2 | | | `---| add 2 | | mul 2 |
113 ; | +---------+ | +--v--+ +-------+ imul +-------+
114 ; | | stage 1 | | | alu | | add 3 | ,--------| mul 3 |
115 ; | +---------+ | +--v--+ +-------+ | +-------+
116 ; | | stage 0 | | | | add 4 | | | mul 4 |
117 ; | +--v---v--+ | | +---v---+ | +-------+
118 ; | | | | | | | | mul 5 |
119 ; | * | | | | | +---v---+
120 ; | | | | | +----v----+ |
121 ; | load | | | fp add `------>| fp last |<------' fp mul
122 ; | | | | +---v-v--^+
124 ; | | | | | `--' dp dest
125 ; | | +--v-----v--+ |
126 ; | `--->| writeback |<--------------------'
129 ; `------------------' *
131 ; The decode unit need not be specified.
132 ; Consideration of writeback contention is critical to superb scheduling.
134 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
135 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
137 ; Describing the '100 alu is currently not useful.
138 ;(define_function_unit "alu" 1 0 (eq_attr "type"
139 ; "!store,marith,weird") 1 0)
140 ;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,weird") 2 0)
142 (define_function_unit "alu" 1 0
143 (and (eq_attr "type" "loada,arith,mov") (eq_attr "cpu" "!m88100")) 2 0)
144 (define_function_unit "alu" 1 0
145 (and (eq_attr "type" "marith,weird") (eq_attr "cpu" "!m88100")) 4 0)
147 (define_function_unit "bit" 1 0
148 (and (eq_attr "type" "bit") (eq_attr "cpu" "!m88100")) 2 2)
150 (define_function_unit "mem100" 1 0
151 (and (eq_attr "type" "store,loada") (eq_attr "cpu" "m88100")) 1 0)
152 (define_function_unit "mem100" 1 0
153 (and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 0)
154 (define_function_unit "mem100" 1 0
155 (and (eq_attr "type" "loadd") (eq_attr "cpu" "m88100")) 3 2)
157 (define_function_unit "mem110" 1 0
158 (and (eq_attr "type" "load,loadd") (eq_attr "cpu" "!m88100")) 3 2)
159 (define_function_unit "mem110" 1 0
160 (and (eq_attr "type" "store") (eq_attr "cpu" "!m88100")) 1 2)
162 ; The times are adjusted to include fp1 and fplast, but then are further
163 ; adjusted based on the actual generated code. The notation to the right
164 ; is the total latency. A range denotes a group of instructions and/or
165 ; conditions (the extra clock of fplast time with some sequences).
167 (define_function_unit "fpmul100" 1 0
168 (and (eq_attr "type" "spmul") (eq_attr "cpu" "m88100")) 4 0) ; 6-8
169 (define_function_unit "fpmul100" 1 0
170 (and (eq_attr "type" "dpmul") (eq_attr "cpu" "m88100")) 7 0) ; 9-10
171 (define_function_unit "fpmul100" 1 0
172 (and (eq_attr "type" "imul") (eq_attr "cpu" "m88100")) 3 0) ; 4
174 (define_function_unit "fpmul110" 1 0
175 (and (eq_attr "type" "imul,spmul,dpmul")
176 (eq_attr "cpu" "!m88100")) 5 2) ; 3
178 (define_function_unit "fpadd100" 1 5
179 (and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 0) ; 5-6
180 (define_function_unit "fpadd100" 1 5
181 (and (eq_attr "type" "dpadd,dpcmp") (eq_attr "cpu" "m88100")) 4 0) ; 6-7
183 (define_function_unit "fpadd110" 1 0
184 (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 5 2) ; 3
185 (define_function_unit "fpadd110" 1 0
186 (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 1
188 (define_function_unit "fpadd100" 1 5
189 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "m88100")) 30 0) ; 30-31
190 (define_function_unit "fpadd100" 1 5
191 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "m88100")) 60 0) ; 60-61
192 (define_function_unit "fpadd100" 1 5
193 (and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 0) ; 38
195 (define_function_unit "div" 1 1
196 (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 25 2) ; 13
197 (define_function_unit "div" 1 1
198 (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 45 2) ; 23
199 (define_function_unit "div" 1 1
200 (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 35 2) ; 18
202 ;; Superoptimizer sequences
204 ;; geu+: { r = ((unsigned_word) v0 >= (unsigned_word) v1) + v2; }
209 [(set (match_operand:SI 0 "register_operand" "=r")
210 (minus:SI (match_operand:SI 1 "register_operand" "r")
211 (geu:SI (match_operand:SI 2 "register_operand" "r")
212 (match_operand:SI 3 "register_operand" "r"))))]
214 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
216 (plus:SI (match_dup 1)
217 (unspec:SI [(const_int 0)
221 ;; leu+: { r = ((unsigned_word) v0 <= (unsigned_word) v1) + v2; }
226 [(set (match_operand:SI 0 "register_operand" "=r")
227 (minus:SI (match_operand:SI 1 "register_operand" "r")
228 (leu:SI (match_operand:SI 3 "register_operand" "r")
229 (match_operand:SI 2 "register_operand" "r"))))]
231 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
233 (plus:SI (match_dup 1)
234 (unspec:SI [(const_int 0)
238 ;; eq0+: { r = (v0 == 0) + v1; }
243 [(set (match_operand:SI 0 "register_operand" "=r")
244 (minus:SI (match_operand:SI 1 "register_operand" "r")
245 (eq:SI (match_operand:SI 2 "register_operand" "r")
248 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
250 (plus:SI (match_dup 1)
251 (unspec:SI [(const_int 0)
255 ;; ltu-: { r = v2 - ((unsigned_word) v0 < (unsigned_word) v1); }
260 [(set (match_operand:SI 0 "register_operand" "=r")
261 (plus:SI (ltu:SI (match_operand:SI 2 "register_operand" "r")
262 (match_operand:SI 3 "register_operand" "r"))
263 (match_operand:SI 1 "register_operand" "r")))]
265 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
267 (minus:SI (match_dup 1)
268 (unspec:SI [(const_int 0)
272 ;; gtu-: { r = v2 - ((unsigned_word) v0 > (unsigned_word) v1); }
277 [(set (match_operand:SI 0 "register_operand" "=r")
278 (plus:SI (gtu:SI (match_operand:SI 3 "register_operand" "r")
279 (match_operand:SI 2 "register_operand" "r"))
280 (match_operand:SI 1 "register_operand" "r")))]
282 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 3)] 1))
284 (minus:SI (match_dup 1)
285 (unspec:SI [(const_int 0)
289 ;; ne0-: { r = v1 - (v0 != 0); }
294 [(set (match_operand:SI 0 "register_operand" "=r")
295 (plus:SI (ne:SI (match_operand:SI 2 "register_operand" "r")
297 (match_operand:SI 1 "register_operand" "r")))]
299 [(set (reg:CC 0) (unspec:CC [(const_int 0) (match_dup 2)] 1))
301 (minus:SI (match_dup 1)
302 (unspec:SI [(const_int 0)
306 ;; ges0-: { r = v1 - ((signed_word) v0 >= 0); }
311 [(set (match_operand:SI 0 "register_operand" "=r")
312 (minus:SI (match_operand:SI 1 "register_operand" "r")
314 (match_operand:SI 2 "register_operand" "r")
318 [(set (reg:CC 0) (unspec:CC [(match_dup 2) (match_dup 2)] 0))
320 (minus:SI (match_dup 1)
321 (unspec:SI [(const_int 0)
325 ;; This rich set of complex patterns are mostly due to Torbjorn Granlund
326 ;; (tege@sics.se). They've changed since then, so don't complain to him
327 ;; if they don't work right.
329 ;; Regarding shifts, gen_lshlsi3 generates ASHIFT. The gen functions
330 ;; produce the necessary insns to support TARGET_*_LARGE_SHIFT, so nothing
331 ;; special needs to be done here.
333 ;; Optimize possible cases of the set instruction.
336 [(set (match_operand:SI 0 "register_operand" "=r")
337 (ashift:SI (const_int -1)
338 (match_operand:SI 1 "register_operand" "r")))]
341 [(set_attr "type" "bit")])
344 [(set (match_operand:SI 0 "register_operand" "=r")
345 (ior:SI (ashift:SI (const_int -1)
346 (match_operand:SI 1 "register_operand" "r"))
347 (match_operand:SI 2 "register_operand" "r")))]
350 [(set_attr "type" "bit")])
353 [(set (match_operand:SI 0 "register_operand" "=r")
354 (ior:SI (match_operand:SI 1 "register_operand" "r")
355 (ashift:SI (const_int -1)
356 (match_operand:SI 2 "register_operand" "r"))))]
359 [(set_attr "type" "bit")])
361 ;; Optimize possible cases of the mak instruction.
364 [(set (match_operand:SI 0 "register_operand" "=r")
365 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
366 (match_operand:SI 2 "int5_operand" ""))
367 (match_operand:SI 3 "immediate_operand" "n")))]
368 "mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2]))"
371 operands[4] = gen_rtx (CONST_INT, SImode,
372 exact_log2 (1 + (INTVAL (operands[3])
373 >> INTVAL(operands[2]))));
374 return \"mak %0,%1,%4<%2>\";
376 [(set_attr "type" "bit")])
378 ;; Optimize possible cases of output_and.
381 [(set (match_operand:SI 0 "register_operand" "=r")
382 (ashift:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
383 (match_operand:SI 2 "int5_operand" "")
384 (match_operand:SI 3 "int5_operand" ""))
385 (match_operand:SI 4 "int5_operand" "")))]
386 "INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
390 = gen_rtx (CONST_INT, SImode,
391 ((1 << INTVAL (operands[2])) - 1) << INTVAL (operands[4]));
392 return output_and (operands);
394 [(set_attr "type" "marith")]) ; arith,bit,marith. length is 1 or 2.
396 ;; Improve logical operations on compare words
398 ;; We define all logical operations on CCmode values to preserve the pairwise
399 ;; relationship of the compare bits. This allows a future branch prediction
400 ;; pass the degree of freedom needed to change and/bb0-le into or/bb1-gt.
401 ;; THIS IS CURRENTLY FALSE!
403 ;; Opportunities arise when conditional expressions using && and || are made
404 ;; unconditional. When these are used to branch, the sequence is
405 ;; cmp/cmp/extu/extu/{and,or}/bcnd-{eq0,ne0}. When these are used to create
406 ;; a value, the sequence is cmp/cmp/extu/extu/{and,or} for 1 or 0 or
407 ;; cmp/cmp/ext/ext/{and,or} for -1 or 0.
409 ;; When the extracted conditions are the same, the define_split patterns
410 ;; below change extu/extu/{and,or} into {and,or}/extu. If the reversed
411 ;; conditions match, one compare word can be complimented, resulting in
412 ;; {and.c,or.c}/extu. These changes are done for ext/ext/{and,or} as well.
413 ;; If the conditions don't line up, one can be rotated. To keep the pairwise
414 ;; relationship, it may be necessary to both rotate and compliment. Rotating
415 ;; makes branching cheaper, but doesn't help (or hurt) creating a value, so
416 ;; we don't do this for ext/ext/{and,or}.
418 ;; These changes result in the sequence extu/bcnd-{eq0,ne0} which is combined
419 ;; into an alternate form of bb0 and bb1.
422 [(set (match_operand:SI 0 "register_operand" "=r")
424 (match_operator 1 "even_relop"
425 [(match_operand 2 "partial_ccmode_register_operand" "%r")
428 (match_operator 3 "relop"
429 [(match_operand 4 "partial_ccmode_register_operand" "r")
431 (clobber (match_operand:SI 5 "register_operand" "=r"))]
434 (ior:CCEVEN (match_dup 4)
437 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
438 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
439 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
440 ; /* The conditions match. */
441 else if (GET_CODE (operands[1])
442 == reverse_condition (GET_CODE (operands[3])))
443 /* Reverse the condition by complimenting the compare word. */
444 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
447 /* Make the condition pairs line up by rotating the compare word. */
448 int cv1 = condition_value (operands[1]);
449 int cv2 = condition_value (operands[3]);
451 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
452 gen_rtx (CONST_INT, VOIDmode,
453 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
454 /* Reverse the condition if needed. */
455 if ((cv1 & 1) != (cv2 & 1))
456 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
460 [(set (match_operand:SI 0 "register_operand" "=r")
462 (match_operator 1 "odd_relop"
463 [(match_operand 2 "partial_ccmode_register_operand" "%r")
466 (match_operator 3 "odd_relop"
467 [(match_operand 4 "partial_ccmode_register_operand" "r")
469 (clobber (match_operand:SI 5 "register_operand" "=r"))]
472 (and:CCEVEN (match_dup 4)
475 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
476 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
477 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
478 ; /* The conditions match. */
481 /* Make the condition pairs line up by rotating the compare word. */
482 int cv1 = condition_value (operands[1]);
483 int cv2 = condition_value (operands[3]);
485 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
486 gen_rtx (CONST_INT, VOIDmode,
487 (cv2 - cv1) & 0x1f));
491 [(set (match_operand:SI 0 "register_operand" "=r")
493 (match_operator 1 "odd_relop"
494 [(match_operand 2 "partial_ccmode_register_operand" "%r")
497 (match_operator 3 "even_relop"
498 [(match_operand 4 "partial_ccmode_register_operand" "r")
500 (clobber (match_operand:SI 5 "register_operand" "=r"))]
503 (ior:CCEVEN (not:CC (match_dup 2))
506 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
507 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
508 if (GET_CODE (operands[1])
509 == reverse_condition (GET_CODE (operands[3])))
513 /* Make the condition pairs line up by rotating the compare word. */
514 int cv1 = condition_value (operands[1]);
515 int cv2 = condition_value (operands[3]);
517 operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
518 gen_rtx (CONST_INT, VOIDmode,
519 ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
523 [(set (match_operand:SI 0 "register_operand" "=r")
524 (ior:SI (match_operator 1 "even_relop"
525 [(match_operand 2 "partial_ccmode_register_operand" "%r")
527 (match_operator 3 "relop"
528 [(match_operand 4 "partial_ccmode_register_operand" "r")
530 (clobber (match_operand:SI 5 "register_operand" "=r"))]
531 "GET_CODE (operands[1]) == GET_CODE (operands[3])
532 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
534 (ior:CCEVEN (match_dup 4)
537 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
538 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
539 /* Reverse the condition by complimenting the compare word. */
540 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
541 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
544 [(set (match_operand:SI 0 "register_operand" "=r")
545 (ior:SI (match_operator 1 "odd_relop"
546 [(match_operand 2 "partial_ccmode_register_operand" "%r")
548 (match_operator 3 "odd_relop"
549 [(match_operand 4 "partial_ccmode_register_operand" "r")
551 (clobber (match_operand:SI 5 "register_operand" "=r"))]
552 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
554 (and:CCEVEN (match_dup 4)
557 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
558 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
561 [(set (match_operand:SI 0 "register_operand" "=r")
562 (ior:SI (match_operator 1 "odd_relop"
563 [(match_operand 2 "partial_ccmode_register_operand" "%r")
565 (match_operator 3 "even_relop"
566 [(match_operand 4 "partial_ccmode_register_operand" "r")
568 (clobber (match_operand:SI 5 "register_operand" "=r"))]
569 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
571 (ior:CCEVEN (not:CC (match_dup 4))
574 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
575 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
578 [(set (match_operand:SI 0 "register_operand" "=r")
580 (match_operator 1 "even_relop"
581 [(match_operand 2 "partial_ccmode_register_operand" "%r")
584 (match_operator 3 "relop"
585 [(match_operand 4 "partial_ccmode_register_operand" "r")
587 (clobber (match_operand:SI 5 "register_operand" "=r"))]
590 (and:CCEVEN (match_dup 4)
593 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
594 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
595 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
596 ; /* The conditions match. */
597 else if (GET_CODE (operands[1])
598 == reverse_condition (GET_CODE (operands[3])))
599 /* Reverse the condition by complimenting the compare word. */
600 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
603 /* Make the condition pairs line up by rotating the compare word. */
604 int cv1 = condition_value (operands[1]);
605 int cv2 = condition_value (operands[3]);
606 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
607 gen_rtx (CONST_INT, VOIDmode,
608 ((cv2 & ~1) - (cv1 & ~1)) & 0x1f));
609 /* Reverse the condition if needed. */
610 if ((cv1 & 1) != (cv2 & 1))
611 operands[4] = gen_rtx (NOT, CCmode, operands[4]);
615 [(set (match_operand:SI 0 "register_operand" "=r")
617 (match_operator 1 "odd_relop"
618 [(match_operand 2 "partial_ccmode_register_operand" "%r")
621 (match_operator 3 "odd_relop"
622 [(match_operand 4 "partial_ccmode_register_operand" "r")
624 (clobber (match_operand:SI 5 "register_operand" "=r"))]
627 (ior:CCEVEN (match_dup 4)
630 (neg:SI (match_op_dup 1 [(match_dup 5) (const_int 0)])))]
631 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
632 if (GET_CODE (operands[1]) == GET_CODE (operands[3]))
633 ; /* The conditions match. */
636 /* Make the condition pairs line up by rotating the compare word. */
637 int cv1 = condition_value (operands[1]);
638 int cv2 = condition_value (operands[3]);
639 operands[4] = gen_rtx (ROTATE, CCmode, operands[4],
640 gen_rtx (CONST_INT, VOIDmode,
641 (cv2 - cv1) & 0x1f));
645 [(set (match_operand:SI 0 "register_operand" "=r")
647 (match_operator 1 "odd_relop"
648 [(match_operand 2 "partial_ccmode_register_operand" "%r")
651 (match_operator 3 "even_relop"
652 [(match_operand 4 "partial_ccmode_register_operand" "r")
654 (clobber (match_operand:SI 5 "register_operand" "=r"))]
657 (and:CCEVEN (not:CC (match_dup 2))
660 (neg:SI (match_op_dup 3 [(match_dup 5) (const_int 0)])))]
661 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
662 if (GET_CODE (operands[1])
663 == reverse_condition (GET_CODE (operands[3])))
667 /* Make the condition pairs line up by rotating the compare word. */
668 int cv1 = condition_value (operands[1]);
669 int cv2 = condition_value (operands[3]);
670 operands[2] = gen_rtx (ROTATE, CCmode, operands[2],
671 gen_rtx (CONST_INT, VOIDmode,
672 ((cv1 & ~1) - (cv2 & ~1)) & 0x1f));
676 [(set (match_operand:SI 0 "register_operand" "=r")
677 (and:SI (match_operator 1 "even_relop"
678 [(match_operand 2 "partial_ccmode_register_operand" "%r")
680 (match_operator 3 "relop"
681 [(match_operand 4 "partial_ccmode_register_operand" "r")
683 (clobber (match_operand:SI 5 "register_operand" "=r"))]
684 "GET_CODE (operands[1]) == GET_CODE (operands[3])
685 || GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
687 (and:CCEVEN (match_dup 4)
690 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
691 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);
692 /* Reverse the condition by complimenting the compare word. */
693 if (GET_CODE (operands[1]) != GET_CODE (operands[3]))
694 operands[4] = gen_rtx (NOT, CCmode, operands[4]);")
697 [(set (match_operand:SI 0 "register_operand" "=r")
698 (and:SI (match_operator 1 "odd_relop"
699 [(match_operand 2 "partial_ccmode_register_operand" "%r")
701 (match_operator 3 "odd_relop"
702 [(match_operand 4 "partial_ccmode_register_operand" "r")
704 (clobber (match_operand:SI 5 "register_operand" "=r"))]
705 "GET_CODE (operands[1]) == GET_CODE (operands[3])"
707 (ior:CCEVEN (match_dup 4)
710 (match_op_dup 1 [(match_dup 5) (const_int 0)]))]
711 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
714 [(set (match_operand:SI 0 "register_operand" "=r")
715 (and:SI (match_operator 1 "odd_relop"
716 [(match_operand 2 "partial_ccmode_register_operand" "%r")
718 (match_operator 3 "even_relop"
719 [(match_operand 4 "partial_ccmode_register_operand" "r")
721 (clobber (match_operand:SI 5 "register_operand" "=r"))]
722 "GET_CODE (operands[1]) == reverse_condition (GET_CODE (operands[3]))"
724 (and:CCEVEN (not:CC (match_dup 2))
727 (match_op_dup 3 [(match_dup 5) (const_int 0)]))]
728 "operands[5] = gen_rtx(SUBREG, CCEVENmode, operands[5], 0);")
731 ;; Logical operations on compare words.
734 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
735 (and:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
736 (match_operand 2 "partial_ccmode_register_operand" "r")))]
741 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
742 (and:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
743 (match_operand 2 "partial_ccmode_register_operand" "r")))]
748 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
749 (ior:CCEVEN (not:CC (match_operand 1 "partial_ccmode_register_operand" "r"))
750 (match_operand 2 "partial_ccmode_register_operand" "r")))]
755 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
756 (ior:CCEVEN (match_operand 1 "partial_ccmode_register_operand" "%r")
757 (match_operand 2 "partial_ccmode_register_operand" "r")))]
762 [(set (match_operand:CC 0 "register_operand" "=r")
763 (rotate:CC (match_operand:CC 1 "register_operand" "r")
764 (match_operand:CC 2 "int5_operand" "")))]
767 [(set_attr "type" "bit")])
770 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
771 (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
772 (match_operand:CC 2 "int5_operand" "")))]
775 [(set_attr "type" "bit")])
777 ;; rotate/and[.c] and rotate/ior[.c]
780 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
781 (ior:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
782 (match_operand:CC 2 "int5_operand" ""))
783 (match_operand 3 "partial_ccmode_register_operand" "r")))
784 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
787 (rotate:CC (match_dup 1) (match_dup 2)))
789 (ior:CCEVEN (match_dup 4) (match_dup 3)))]
793 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
794 (ior:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
795 (match_operand:CC 2 "int5_operand" ""))
796 (match_operand 3 "partial_ccmode_register_operand" "r")))
797 (clobber (match_scratch:CCEVEN 4 "=r"))]
802 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
803 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
804 (match_operand:CC 2 "int5_operand" "")))
805 (match_operand 3 "partial_ccmode_register_operand" "r")))
806 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
809 (rotate:CC (match_dup 1) (match_dup 2)))
811 (ior:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
815 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
816 (ior:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
817 (match_operand:CC 2 "int5_operand" "")))
818 (match_operand 3 "partial_ccmode_register_operand" "r")))
819 (clobber (match_scratch:CCEVEN 4 "=r"))]
824 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
825 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
826 (match_operand:CC 2 "int5_operand" ""))
827 (match_operand 3 "partial_ccmode_register_operand" "r")))
828 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
831 (rotate:CC (match_dup 1) (match_dup 2)))
833 (and:CCEVEN (match_dup 4) (match_dup 3)))]
837 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
838 (and:CCEVEN (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
839 (match_operand:CC 2 "int5_operand" ""))
840 (match_operand 3 "partial_ccmode_register_operand" "r")))
841 (clobber (match_scratch:CCEVEN 4 "=r"))]
846 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
847 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
848 (match_operand:CC 2 "int5_operand" "")))
849 (match_operand 3 "partial_ccmode_register_operand" "r")))
850 (clobber (match_operand:CCEVEN 4 "register_operand" "=r"))]
853 (rotate:CC (match_dup 1) (match_dup 2)))
855 (and:CCEVEN (not:CC (match_dup 4)) (match_dup 3)))]
859 [(set (match_operand:CCEVEN 0 "register_operand" "=r")
860 (and:CCEVEN (not:CC (rotate:CC (match_operand 1 "partial_ccmode_register_operand" "r")
861 (match_operand:CC 2 "int5_operand" "")))
862 (match_operand 3 "partial_ccmode_register_operand" "r")))
863 (clobber (match_scratch:CCEVEN 4 "=r"))]
868 ;; Recognize bcnd instructions for integer values. This is distinguished
869 ;; from a conditional branch instruction (below) with SImode instead of
875 (match_operator 0 "relop_no_unsigned"
876 [(match_operand:SI 1 "register_operand" "r")
878 (match_operand 2 "pc_or_label_ref" "")
879 (match_operand 3 "pc_or_label_ref" "")))]
881 "bcnd%. %R3%B0,%1,%P2%P3"
882 [(set_attr "type" "branch")])
884 ;; Recognize tests for sign and zero.
889 (match_operator 0 "equality_op"
890 [(match_operand:SI 1 "register_operand" "r")
891 (const_int -2147483648)])
892 (match_operand 2 "pc_or_label_ref" "")
893 (match_operand 3 "pc_or_label_ref" "")))]
895 "bcnd%. %R3%E0,%1,%P2%P3"
896 [(set_attr "type" "branch")])
901 (match_operator 0 "equality_op"
903 (match_operand:SI 1 "register_operand" "r")
907 (match_operand 2 "pc_or_label_ref" "")
908 (match_operand 3 "pc_or_label_ref" "")))]
910 "bcnd%. %R3%D0,%1,%P2%P3"
911 [(set_attr "type" "branch")])
913 ;; Recognize bcnd instructions for double integer values
918 (match_operator 0 "relop_no_unsigned"
920 (match_operand:SI 1 "register_operand" "r"))
922 (match_operand 2 "pc_or_label_ref" "")
923 (match_operand 3 "pc_or_label_ref" "")))]
925 "bcnd%. %R3%B0,%1,%P2%P3"
926 [(set_attr "type" "branch")])
931 (match_operator 0 "equality_op"
933 (match_operand:SI 1 "register_operand" "r"))
935 (match_operand 2 "pc_or_label_ref" "")
936 (match_operand 3 "pc_or_label_ref" "")))]
938 "bcnd%. %R3%B0,%1,%P2%P3"
939 [(set_attr "type" "branch")])
941 ; @@ I doubt this is interesting until cmpdi is provided. Anyway, it needs
947 ; (match_operator 0 "relop_no_unsigned"
948 ; [(match_operand:DI 1 "register_operand" "r")
950 ; (match_operand 2 "pc_or_label_ref" "")
951 ; (match_operand 3 "pc_or_label_ref" "")))]
955 ; switch (GET_CODE (operands[0]))
959 ; /* I'm not sure if it's safe to use .n here. */
960 ; return \"or %!,%1,%d1\;bcnd %R3%B0,%!,%P2%P3\";
963 ; return \"bcnd%. %R3%B0,%1,%P2%P3\";
966 ; rtx op2 = operands[2];
967 ; operands[2] = operands[3];
971 ; if (GET_CODE (operands[3]) == LABEL_REF)
974 ; operands[2] = gen_label_rtx ();
975 ; label_num = XINT (operands[2], 3);
977 ; (\"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#ne0,%!,%3\", operands);
978 ; output_label (label_num);
982 ; return \"bcnd%. %#lt0,%1,%2\;or %!,%1,%d1\;bcnd %#eq0,%!,%2\";
986 ;; Recognize bcnd instructions for single precision float values
987 ;; Exclude relational operations as they must signal NaNs.
989 ;; @@ These bcnd insns for float and double values don't seem to be recognized.
994 (match_operator 0 "equality_op"
996 (match_operand:SF 1 "register_operand" "r"))
998 (match_operand 2 "pc_or_label_ref" "")
999 (match_operand 3 "pc_or_label_ref" "")))]
1001 "bcnd%. %R3%D0,%1,%P2%P3"
1002 [(set_attr "type" "branch")])
1007 (match_operator 0 "equality_op"
1008 [(match_operand:SF 1 "register_operand" "r")
1010 (match_operand 2 "pc_or_label_ref" "")
1011 (match_operand 3 "pc_or_label_ref" "")))]
1013 "bcnd%. %R3%D0,%1,%P2%P3"
1014 [(set_attr "type" "branch")])
1016 ;; Recognize bcnd instructions for double precision float values
1017 ;; Exclude relational operations as they must signal NaNs.
1022 (match_operator 0 "equality_op"
1023 [(match_operand:DF 1 "register_operand" "r")
1025 (match_operand 2 "pc_or_label_ref" "")
1026 (match_operand 3 "pc_or_label_ref" "")))]
1032 if (GET_CODE (operands[0]) == NE)
1034 rtx op2 = operands[2];
1035 operands[2] = operands[3];
1038 if (GET_CODE (operands[3]) == LABEL_REF)
1039 return \"bcnd 0x5,%1,%3\;bcnd %#ne0,%d1,%3\";
1041 operands[3] = gen_label_rtx ();
1042 label_num = XINT (operands[3], 3);
1043 output_asm_insn (\"bcnd 0x5,%1,%3\;bcnd %#eq0,%d1,%2\", operands);
1044 output_label (label_num);
1047 [(set_attr "type" "weird")
1048 (set_attr "length" "3")])
1050 ;; Recognize bb0 and bb1 instructions. These use two unusual template
1051 ;; patterns, %Lx and %Px. %Lx outputs a 1 if operand `x' is a LABEL_REF
1052 ;; otherwise it outputs a 0. It then may print ".n" if the delay slot
1053 ;; is used. %Px does noting if `x' is PC and outputs the operand if `x'
1059 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1061 (match_operand:SI 1 "int5_operand" ""))
1063 (match_operand 2 "pc_or_label_ref" "")
1064 (match_operand 3 "pc_or_label_ref" "")))]
1066 "bb%L2 (31-%1),%0,%P2%P3"
1067 [(set_attr "type" "branch")])
1072 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
1074 (match_operand:SI 1 "int5_operand" ""))
1076 (match_operand 2 "pc_or_label_ref" "")
1077 (match_operand 3 "pc_or_label_ref" "")))]
1079 "bb%L3 (31-%1),%0,%P2%P3"
1080 [(set_attr "type" "branch")])
1085 (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1087 (match_operand:SI 1 "int5_operand" ""))
1089 (match_operand 2 "pc_or_label_ref" "")
1090 (match_operand 3 "pc_or_label_ref" "")))]
1092 "bb%L2 (31-%1),%0,%P2%P3"
1093 [(set_attr "type" "branch")])
1098 (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1100 (match_operand:SI 1 "int5_operand" ""))
1102 (match_operand 2 "pc_or_label_ref" "")
1103 (match_operand 3 "pc_or_label_ref" "")))]
1105 "bb%L3 (31-%1),%0,%P2%P3"
1106 [(set_attr "type" "branch")])
1111 (eq (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1112 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1114 (match_operand 2 "pc_or_label_ref" "")
1115 (match_operand 3 "pc_or_label_ref" "")))]
1116 "(GET_CODE (operands[0]) == CONST_INT)
1117 != (GET_CODE (operands[1]) == CONST_INT)"
1118 "bb%L3 %p1,%0,%P2%P3"
1119 [(set_attr "type" "branch")])
1124 (ne (and:SI (match_operand:SI 0 "reg_or_bbx_mask_operand" "%r")
1125 (match_operand:SI 1 "reg_or_bbx_mask_operand" "n"))
1127 (match_operand 2 "pc_or_label_ref" "")
1128 (match_operand 3 "pc_or_label_ref" "")))]
1129 "(GET_CODE (operands[0]) == CONST_INT)
1130 != (GET_CODE (operands[1]) == CONST_INT)"
1131 "bb%L2 %p1,%0,%P2%P3"
1132 [(set_attr "type" "branch")])
1134 ;; The comparison operations store the comparison into a register and
1135 ;; record that register. The following Bxx or Sxx insn uses that
1136 ;; register as an input. To facilitate use of bcnd instead of cmp/bb1,
1137 ;; cmpsi records it's operands and produces no code when any operand
1138 ;; is constant. In this case, the Bxx insns use gen_bcnd and the
1139 ;; Sxx insns use gen_test to ensure a cmp has been emitted.
1141 ;; This could also be done for SFmode and DFmode having only beq and bne
1142 ;; use gen_bcnd. The others must signal NaNs. It seems though that zero
1143 ;; has already been copied into a register.
1145 ;; cmpsi/beq and cmpsi/bne can always be done with bcnd if any operand
1146 ;; is a constant. (This idea is due to Torbjorn Granlund.) Others can
1147 ;; use bcnd only if an operand is zero.
1149 ;; It is necessary to distinguish a register holding condition codes.
1150 ;; This is done by context.
1152 (define_expand "test"
1154 (compare:CC (match_operand 0 "" "")
1155 (match_operand 1 "" "")))]
1159 if (m88k_compare_reg)
1162 if (GET_CODE (operands[0]) == CONST_INT
1163 && ! SMALL_INT (operands[0]))
1164 operands[0] = force_reg (SImode, operands[0]);
1166 if (GET_CODE (operands[1]) == CONST_INT
1167 && ! SMALL_INT (operands[1]))
1168 operands[1] = force_reg (SImode, operands[1]);
1170 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1173 ; @@ The docs say don't do this. It's probably a nop since the insn looks
1174 ; identical to cmpsi against zero. Is there an advantage to providing
1175 ; this, perhaps with a different form?
1177 ;(define_expand "tstsi"
1178 ; [(set (match_dup 1)
1179 ; (compare:CC (match_operand:SI 0 "register_operand" "")
1184 ; m88k_compare_reg = 0;
1185 ; m88k_compare_op0 = operands[0];
1186 ; m88k_compare_op1 = const0_rtx;
1190 (define_expand "cmpsi"
1192 (compare:CC (match_operand:SI 0 "register_operand" "")
1193 (match_operand:SI 1 "arith32_operand" "")))]
1197 if (GET_CODE (operands[0]) == CONST_INT
1198 || GET_CODE (operands[1]) == CONST_INT)
1200 m88k_compare_reg = 0;
1201 m88k_compare_op0 = operands[0];
1202 m88k_compare_op1 = operands[1];
1205 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1208 (define_expand "cmpsf"
1210 (compare:CC (match_operand:SF 0 "register_operand" "")
1211 (match_operand:SF 1 "register_operand" "")))]
1213 "operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);")
1215 (define_expand "cmpdf"
1217 (compare:CC (match_operand:DF 0 "general_operand" "")
1218 (match_operand:DF 1 "general_operand" "")))]
1222 operands[0] = legitimize_operand (operands[0], DFmode);
1223 operands[1] = legitimize_operand (operands[1], DFmode);
1224 operands[2] = m88k_compare_reg = gen_reg_rtx (CCmode);
1227 ; @@ Get back to this later on.
1229 ;(define_insn "cmpdi"
1231 ; (compare:CC (match_operand:DI 0 "register_operand" "r")
1232 ; (match_operand:DI 1 "register_operand" "r")))]
1236 ; if ((cc_status.mdep & MDEP_LS_CHANGE) != 0)
1237 ; abort (); /* output_move_double MDEP_LS_CHANGE bits were set. */
1239 ; cc_status.mdep &= ~ MDEP_LS_MASK;
1241 ; operands[2] = gen_label_rtx ();
1242 ; /* Remember, %! is the condition code register and %@ is the
1243 ; literal synthesis register. */
1245 ; output_asm_insn (\"cmp %!,%0,%1\;bb0 %#eq,%!,%l2\;cmp %!,%d0,%d1\",
1248 ; output_asm_insn (\"extu %@,%!,4<8>\;clr %!,%!,4<4>\", operands);
1249 ; output_asm_insn (\"mak %@,%@,4<4>\;or %!,%!,%@\", operands);
1250 ; output_label (XINT (operands[2], 3));
1254 ;; The actual compare instructions.
1257 [(set (match_operand:CC 0 "register_operand" "=r")
1258 (compare:CC (match_operand:SI 1 "register_operand" "rO")
1259 (match_operand:SI 2 "arith_operand" "rI")))]
1264 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1265 (compare:CC (match_operand:SF 1 "register_operand" "r,r,x,x")
1266 (match_operand:SF 2 "real_or_0_operand" "r,G,x,G")))]
1272 fcmp.sss %0,%1,%#x0"
1273 [(set_attr "type" "spcmp")])
1276 [(set (match_operand:CC 0 "register_operand" "=r,r")
1277 (compare:CC (match_operand:DF 1 "register_operand" "r,x")
1279 (match_operand:SF 2 "register_operand" "r,x"))))]
1282 [(set_attr "type" "dpcmp")])
1285 [(set (match_operand:CC 0 "register_operand" "=r,r")
1286 (compare:CC (float_extend:DF
1287 (match_operand:SF 1 "register_operand" "r,x"))
1288 (match_operand:DF 2 "register_operand" "r,x")))]
1291 [(set_attr "type" "dpcmp")])
1294 [(set (match_operand:CC 0 "register_operand" "=r,r,r,r")
1295 (compare:CC (match_operand:DF 1 "register_operand" "r,r,x,x")
1296 (match_operand:DF 2 "real_or_0_operand" "r,G,x,G")))]
1302 fcmp.sds %0,%1,%#x0"
1303 [(set_attr "type" "dpcmp")])
1305 ;; Store condition code insns. The compare insns set a register
1306 ;; rather than cc0 and record that register for use here. See above
1307 ;; for the special treatment of cmpsi with a constant operand.
1309 ;; @@ For the m88110, use fcmpu for bxx sxx inequality comparisons.
1311 (define_expand "seq"
1312 [(set (match_operand:SI 0 "register_operand" "")
1315 "operands[1] = emit_test (EQ, SImode);")
1317 (define_expand "sne"
1318 [(set (match_operand:SI 0 "register_operand" "")
1321 "operands[1] = emit_test (NE, SImode);")
1323 (define_expand "sgt"
1324 [(set (match_operand:SI 0 "register_operand" "")
1327 "operands[1] = emit_test (GT, SImode);")
1329 (define_expand "sgtu"
1330 [(set (match_operand:SI 0 "register_operand" "")
1333 "operands[1] = emit_test (GTU, SImode);")
1335 (define_expand "slt"
1336 [(set (match_operand:SI 0 "register_operand" "")
1339 "operands[1] = emit_test (LT, SImode);")
1341 (define_expand "sltu"
1342 [(set (match_operand:SI 0 "register_operand" "")
1345 "operands[1] = emit_test (LTU, SImode);")
1347 (define_expand "sge"
1348 [(set (match_operand:SI 0 "register_operand" "")
1351 "operands[1] = emit_test (GE, SImode);")
1353 (define_expand "sgeu"
1354 [(set (match_operand:SI 0 "register_operand" "")
1357 "operands[1] = emit_test (GEU, SImode);")
1359 (define_expand "sle"
1360 [(set (match_operand:SI 0 "register_operand" "")
1363 "operands[1] = emit_test (LE, SImode);")
1365 (define_expand "sleu"
1366 [(set (match_operand:SI 0 "register_operand" "")
1369 "operands[1] = emit_test (LEU, SImode);")
1371 ;; The actual set condition code instruction.
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (match_operator:SI 1 "relop"
1376 [(match_operand:CC 2 "register_operand" "r")
1380 [(set_attr "type" "bit")])
1383 [(set (match_operand:SI 0 "register_operand" "=r")
1384 (match_operator:SI 1 "even_relop"
1385 [(match_operand:CCEVEN 2 "register_operand" "r")
1389 [(set_attr "type" "bit")])
1392 [(set (match_operand:SI 0 "register_operand" "=r")
1393 (not:SI (match_operator:SI 1 "odd_relop"
1394 [(match_operand:CCEVEN 2 "register_operand" "r")
1397 "ext %0,%2,1<%!%C1>"
1398 [(set_attr "type" "bit")])
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1402 (match_operator:SI 1 "odd_relop"
1403 [(match_operand:CCEVEN 2 "register_operand" "r")
1405 (clobber (match_operand:SI 3 "register_operand" "=r"))]
1407 [(set (match_dup 3) (not:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])))
1408 (set (match_dup 0) (not:SI (match_dup 3)))]
1412 [(set (match_operand:SI 0 "register_operand" "=r")
1413 (match_operator:SI 1 "odd_relop"
1414 [(match_operand:CCEVEN 2 "register_operand" "r")
1416 (clobber (match_scratch:SI 3 "=r"))]
1421 [(set (match_operand:SI 0 "register_operand" "=r")
1423 (match_operator:SI 1 "relop"
1424 [(match_operand:CC 2 "register_operand" "r")
1428 [(set_attr "type" "bit")])
1431 [(set (match_operand:SI 0 "register_operand" "=r")
1433 (match_operator:SI 1 "even_relop"
1434 [(match_operand:CCEVEN 2 "register_operand" "r")
1438 [(set_attr "type" "bit")])
1441 [(set (match_operand:SI 0 "register_operand" "=r")
1443 (not:SI (match_operator:SI 1 "odd_relop"
1444 [(match_operand:CCEVEN 2 "register_operand" "r")
1447 "extu %0,%2,1<%!%C1>"
1448 [(set_attr "type" "bit")])
1451 [(set (match_operand:SI 0 "register_operand" "=r")
1452 (neg:SI (match_operator:SI 1 "odd_relop"
1453 [(match_operand:CCEVEN 2 "register_operand" "r")
1455 (clobber (match_operand:SI 3 "register_operand" "=r"))]
1457 [(set (match_dup 3) (neg:SI (not:SI (match_op_dup 1 [(match_dup 2)
1459 (set (match_dup 0) (xor:SI (match_dup 3) (const_int 1)))]
1464 [(set (match_operand:SI 0 "register_operand" "=r")
1465 (neg:SI (match_operator:SI 1 "odd_relop"
1466 [(match_operand:CCEVEN 2 "register_operand" "r")
1468 (clobber (match_scratch:SI 3 "=r"))]
1475 ;; Conditional branch insns. The compare insns set a register
1476 ;; rather than cc0 and record that register for use here. See above
1477 ;; for the special case of cmpsi with a constant operand.
1479 (define_expand "bcnd"
1481 (if_then_else (match_operand 0 "" "")
1482 (label_ref (match_operand 1 "" ""))
1485 "if (m88k_compare_reg) abort ();")
1487 (define_expand "bxx"
1489 (if_then_else (match_operand 0 "" "")
1490 (label_ref (match_operand 1 "" ""))
1493 "if (m88k_compare_reg == 0) abort ();")
1495 (define_expand "beq"
1497 (if_then_else (eq (match_dup 1) (const_int 0))
1498 (label_ref (match_operand 0 "" ""))
1501 "if (m88k_compare_reg == 0)
1503 emit_bcnd (EQ, operands[0]);
1506 operands[1] = m88k_compare_reg;")
1508 (define_expand "bne"
1510 (if_then_else (ne (match_dup 1) (const_int 0))
1511 (label_ref (match_operand 0 "" ""))
1514 "if (m88k_compare_reg == 0)
1516 emit_bcnd (NE, operands[0]);
1519 operands[1] = m88k_compare_reg;")
1521 (define_expand "bgt"
1523 (if_then_else (gt (match_dup 1) (const_int 0))
1524 (label_ref (match_operand 0 "" ""))
1527 "if (m88k_compare_reg == 0)
1529 emit_bcnd (GT, operands[0]);
1532 operands[1] = m88k_compare_reg;")
1534 (define_expand "bgtu"
1536 (if_then_else (gtu (match_dup 1) (const_int 0))
1537 (label_ref (match_operand 0 "" ""))
1540 "if (m88k_compare_reg == 0)
1542 emit_jump_insn (gen_bxx (emit_test (GTU, VOIDmode), operands[0]));
1545 operands[1] = m88k_compare_reg;")
1547 (define_expand "blt"
1549 (if_then_else (lt (match_dup 1) (const_int 0))
1550 (label_ref (match_operand 0 "" ""))
1553 "if (m88k_compare_reg == 0)
1555 emit_bcnd (LT, operands[0]);
1558 operands[1] = m88k_compare_reg;")
1560 (define_expand "bltu"
1562 (if_then_else (ltu (match_dup 1) (const_int 0))
1563 (label_ref (match_operand 0 "" ""))
1566 "if (m88k_compare_reg == 0)
1568 emit_jump_insn (gen_bxx (emit_test (LTU, VOIDmode), operands[0]));
1571 operands[1] = m88k_compare_reg;")
1573 (define_expand "bge"
1575 (if_then_else (ge (match_dup 1) (const_int 0))
1576 (label_ref (match_operand 0 "" ""))
1579 "if (m88k_compare_reg == 0)
1581 emit_bcnd (GE, operands[0]);
1584 operands[1] = m88k_compare_reg;")
1586 (define_expand "bgeu"
1588 (if_then_else (geu (match_dup 1) (const_int 0))
1589 (label_ref (match_operand 0 "" ""))
1592 "if (m88k_compare_reg == 0)
1594 emit_jump_insn (gen_bxx (emit_test (GEU, VOIDmode), operands[0]));
1597 operands[1] = m88k_compare_reg;")
1599 (define_expand "ble"
1601 (if_then_else (le (match_dup 1) (const_int 0))
1602 (label_ref (match_operand 0 "" ""))
1605 "if (m88k_compare_reg == 0)
1607 emit_bcnd (LE, operands[0]);
1610 operands[1] = m88k_compare_reg;")
1612 (define_expand "bleu"
1614 (if_then_else (leu (match_dup 1) (const_int 0))
1615 (label_ref (match_operand 0 "" ""))
1618 "if (m88k_compare_reg == 0)
1620 emit_jump_insn (gen_bxx (emit_test (LEU, VOIDmode), operands[0]));
1623 operands[1] = m88k_compare_reg;")
1625 ;; The actual conditional branch instruction (both directions). This
1626 ;; uses two unusual template patterns, %Rx and %Px. %Rx is a prefix code
1627 ;; for the immediately following condition and reverses the condition iff
1628 ;; operand `x' is a LABEL_REF. %Px does nothing if `x' is PC and outputs
1629 ;; the operand if `x' is a LABEL_REF.
1632 [(set (pc) (if_then_else
1633 (match_operator 0 "relop"
1634 [(match_operand:CC 1 "register_operand" "r")
1636 (match_operand 2 "pc_or_label_ref" "")
1637 (match_operand 3 "pc_or_label_ref" "")))]
1641 if (mostly_false_jump (insn, operands[0]))
1642 return \"bb0%. %R2%C0,%1,%P2%P3\";
1644 return \"bb1%. %R3%C0,%1,%P2%P3\";
1646 [(set_attr "type" "branch")])
1649 ;; Here branch prediction is sacrificed. To get it back, you need
1650 ;; - CCODD (CC mode where the ODD bits are valid)
1651 ;; - several define_split that can apply De Morgan's Law.
1652 ;; - transformations between CCEVEN and CCODD modes.
1656 [(set (pc) (if_then_else
1657 (match_operator 0 "even_relop"
1658 [(match_operand:CCEVEN 1 "register_operand" "r")
1660 (match_operand 2 "pc_or_label_ref" "")
1661 (match_operand 3 "pc_or_label_ref" "")))]
1663 "bb%L2%. %C0,%1,%P2%P3"
1664 [(set_attr "type" "branch")])
1667 [(set (pc) (if_then_else
1668 (match_operator 0 "odd_relop"
1669 [(match_operand:CCEVEN 1 "register_operand" "r")
1671 (match_operand 2 "pc_or_label_ref" "")
1672 (match_operand 3 "pc_or_label_ref" "")))]
1674 "bb%L3%. %!%C0,%1,%P2%P3"
1675 [(set_attr "type" "branch")])
1677 ;; Branch conditional on scc values. These arise from manipulations on
1678 ;; compare words above.
1679 ;; Are these really used ?
1684 (ne (match_operator 0 "relop"
1685 [(match_operand:CC 1 "register_operand" "r")
1688 (match_operand 2 "pc_or_label_ref" "")
1689 (match_operand 3 "pc_or_label_ref" "")))]
1691 "bb%L2 %C0,%1,%P2%P3"
1692 [(set_attr "type" "branch")])
1697 (ne (match_operator 0 "even_relop"
1698 [(match_operand:CCEVEN 1 "register_operand" "r")
1701 (match_operand 2 "pc_or_label_ref" "")
1702 (match_operand 3 "pc_or_label_ref" "")))]
1704 "bb%L2 %C0,%1,%P2%P3"
1705 [(set_attr "type" "branch")])
1710 (ne (match_operator 0 "odd_relop"
1711 [(match_operand:CCEVEN 1 "register_operand" "r")
1714 (match_operand 2 "pc_or_label_ref" "")
1715 (match_operand 3 "pc_or_label_ref" "")))]
1717 "bb%L3 %!%C0,%1,%P2%P3"
1718 [(set_attr "type" "branch")])
1723 (eq (match_operator 0 "relop"
1724 [(match_operand:CC 1 "register_operand" "r")
1727 (match_operand 2 "pc_or_label_ref" "")
1728 (match_operand 3 "pc_or_label_ref" "")))]
1730 "bb%L3 %C0,%1,%P2%P3"
1731 [(set_attr "type" "branch")])
1736 (eq (match_operator 0 "even_relop"
1737 [(match_operand:CCEVEN 1 "register_operand" "r")
1740 (match_operand 2 "pc_or_label_ref" "")
1741 (match_operand 3 "pc_or_label_ref" "")))]
1743 "bb%L3 %C0,%1,%P2%P3"
1744 [(set_attr "type" "branch")])
1749 (eq (match_operator 0 "odd_relop"
1750 [(match_operand:CCEVEN 1 "register_operand" "r")
1753 (match_operand 2 "pc_or_label_ref" "")
1754 (match_operand 3 "pc_or_label_ref" "")))]
1756 "bb%L2 %!%C0,%1,%P2%P3"
1757 [(set_attr "type" "branch")])
1759 (define_insn "locate1"
1760 [(set (match_operand:SI 0 "register_operand" "=r")
1761 (high:SI (unspec:SI [(label_ref (match_operand 1 "" ""))] 0)))]
1763 "or.u %0,%#r0,%#hi16(%1#abdiff)")
1765 (define_insn "locate2"
1766 [(parallel [(set (reg:SI 1) (pc))
1767 (set (match_operand:SI 0 "register_operand" "=r")
1768 (lo_sum:SI (match_dup 0)
1770 [(label_ref (match_operand 1 "" ""))] 0)))])]
1772 "bsr.n %1\;or %0,%0,%#lo16(%1#abdiff)\\n%1:"
1773 [(set_attr "length" "2")])
1775 ;; SImode move instructions
1777 (define_expand "movsi"
1778 [(set (match_operand:SI 0 "general_operand" "")
1779 (match_operand:SI 1 "general_operand" ""))]
1783 if (emit_move_sequence (operands, SImode, 0))
1787 (define_expand "reload_insi"
1788 [(set (match_operand:SI 0 "register_operand" "=r")
1789 (match_operand:SI 1 "general_operand" ""))
1790 (clobber (match_operand:SI 2 "register_operand" "=&r"))]
1794 if (emit_move_sequence (operands, SImode, operands[2]))
1797 /* We don't want the clobber emitted, so handle this ourselves. */
1798 emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
1803 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,x,x,x,m")
1804 (match_operand:SI 1 "move_operand" "rI,m,rO,J,M,x,r,x,m,x"))]
1805 "(register_operand (operands[0], SImode)
1806 || register_operand (operands[1], SImode)
1807 || operands[1] == const0_rtx)"
1819 [(set_attr "type" "arith,load,store,arith,bit,mov,mov,mov,load,store")])
1822 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1823 (match_operand:SI 1 "arith32_operand" "rI,J,L,M,n"))]
1830 or.u %0,%#r0,%X1\;or %0,%0,%x1"
1831 [(set_attr "type" "arith,arith,arith,bit,marith")])
1833 ;; @@ Why the constraint "in"? Doesn't `i' include `n'?
1835 [(set (match_operand:SI 0 "register_operand" "=r")
1836 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1837 (match_operand:SI 2 "immediate_operand" "in")))]
1839 "or %0,%1,%#lo16(%g2)")
1841 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1842 ;; confuse them with real addresses.
1844 [(set (match_operand:SI 0 "register_operand" "=r")
1845 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1846 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1848 "or %0,%1,%#lo16(%g2)"
1849 ;; Need to set length for this arith insn because operand2
1850 ;; is not an "arith_operand".
1851 [(set_attr "length" "1")])
1854 [(set (match_operand:SI 0 "register_operand" "=r")
1855 (high:SI (match_operand 1 "" "")))]
1857 "or.u %0,%#r0,%#hi16(%g1)")
1859 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
1860 ;; confuse them with real addresses.
1862 [(set (match_operand:SI 0 "register_operand" "=r")
1863 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1865 "or.u %0,%#r0,%#hi16(%g1)"
1866 ;; Need to set length for this arith insn because operand2
1867 ;; is not an arith_operand.
1868 [(set_attr "length" "1")])
1870 ;; HImode move instructions
1872 (define_expand "movhi"
1873 [(set (match_operand:HI 0 "general_operand" "")
1874 (match_operand:HI 1 "general_operand" ""))]
1878 if (emit_move_sequence (operands, HImode, 0))
1883 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
1884 (match_operand:HI 1 "move_operand" "rP,m,rO,N"))]
1885 "(register_operand (operands[0], HImode)
1886 || register_operand (operands[1], HImode)
1887 || operands[1] == const0_rtx)"
1893 [(set_attr "type" "arith,load,store,arith")])
1896 [(set (match_operand:HI 0 "register_operand" "=r")
1897 (subreg:HI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1898 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1900 "or %0,%1,%#lo16(%2)")
1902 ;; QImode move instructions
1904 (define_expand "movqi"
1905 [(set (match_operand:QI 0 "general_operand" "")
1906 (match_operand:QI 1 "general_operand" ""))]
1910 if (emit_move_sequence (operands, QImode, 0))
1915 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
1916 (match_operand:QI 1 "move_operand" "rP,m,rO,N"))]
1917 "(register_operand (operands[0], QImode)
1918 || register_operand (operands[1], QImode)
1919 || operands[1] == const0_rtx)"
1925 [(set_attr "type" "arith,load,store,arith")])
1928 [(set (match_operand:QI 0 "register_operand" "=r")
1929 (subreg:QI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1930 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1932 "or %0,%1,%#lo16(%2)")
1934 ;; DImode move instructions
1936 (define_expand "movdi"
1937 [(set (match_operand:DI 0 "general_operand" "")
1938 (match_operand:DI 1 "general_operand" ""))]
1942 if (emit_move_sequence (operands, DImode, 0))
1947 [(set (match_operand:DI 0 "register_operand" "=r,x")
1951 or %0,%#r0,0\;or %d0,%#r0,0
1953 [(set_attr "type" "marith,mov")])
1956 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,x,x,x,m")
1957 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,x,r,x,m,x"))]
1960 or %0,%#r0,%1\;or %d0,%#r0,%d1
1968 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
1971 [(set (match_operand:DI 0 "register_operand" "=r")
1972 (subreg:DI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1973 (match_operand:SI 2 "immediate_operand" "in")) 0))]
1975 "or %0,%1,%#lo16(%2)")
1978 [(set (match_operand:DI 0 "register_operand" "=r")
1979 (match_operand:DI 1 "immediate_operand" "n"))]
1981 "* return output_load_const_dimode (operands);"
1982 [(set_attr "type" "marith")
1983 (set_attr "length" "4")]) ; length is 2, 3 or 4.
1985 ;; DFmode move instructions
1987 (define_expand "movdf"
1988 [(set (match_operand:DF 0 "general_operand" "")
1989 (match_operand:DF 1 "general_operand" ""))]
1993 if (emit_move_sequence (operands, DFmode, 0))
1998 [(set (match_operand:DF 0 "register_operand" "=r")
1999 (match_operand:DF 1 "register_operand" "r"))]
2001 && GET_CODE (operands[0]) == REG && !XRF_REGNO_P (REGNO (operands[0]))
2002 && GET_CODE (operands[1]) == REG && !XRF_REGNO_P (REGNO (operands[1]))"
2003 [(set (match_dup 2) (match_dup 3))
2004 (set (match_dup 4) (match_dup 5))]
2006 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2007 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2008 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2009 operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
2011 ;; @@ This pattern is incomplete and doesn't appear necessary.
2013 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2014 ;; to be reloaded by putting the constant into memory.
2015 ;; It must come before the more general movdf pattern.
2018 ; [(set (match_operand:DF 0 "general_operand" "=r,o")
2019 ; (match_operand:DF 1 "" "G,G"))]
2020 ; "GET_CODE (operands[1]) == CONST_DOUBLE"
2023 ; switch (which_alternative)
2026 ; return \"or %0,%#r0,0\;or %d0,%#r0,0\";
2028 ; operands[1] = adj_offsettable_operand (operands[0], 4);
2029 ; return \"%v0st\\t %#r0,%0\;st %#r0,%1\";
2034 [(set (match_operand:DF 0 "register_operand" "=r,x")
2038 or %0,%#r0,0\;or %d0,%#r0,0
2040 [(set_attr "type" "marith,mov")])
2043 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2044 (match_operand:DF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2047 or %0,%#r0,%1\;or %d0,%#r0,%d1
2055 [(set_attr "type" "marith,loadd,store,mov,mov,mov,loadd,store")])
2058 [(set (match_operand:DF 0 "register_operand" "=r")
2059 (subreg:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2060 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2062 "or %0,%1,%#lo16(%2)")
2065 [(set (match_operand:DF 0 "register_operand" "=r")
2066 (match_operand:DF 1 "immediate_operand" "F"))]
2068 "* return output_load_const_double (operands);"
2069 [(set_attr "type" "marith")
2070 (set_attr "length" "4")]) ; length is 2, 3, or 4.
2072 ;; SFmode move instructions
2074 (define_expand "movsf"
2075 [(set (match_operand:SF 0 "general_operand" "")
2076 (match_operand:SF 1 "general_operand" ""))]
2080 if (emit_move_sequence (operands, SFmode, 0))
2084 ;; @@ What happens to fconst0_rtx?
2086 [(set (match_operand:SF 0 "register_operand" "=r,x")
2092 [(set_attr "type" "arith,mov")])
2095 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,x,r,x,x,m")
2096 (match_operand:SF 1 "nonimmediate_operand" "r,m,r,r,x,x,m,x"))]
2107 [(set_attr "type" "arith,load,store,mov,mov,mov,load,store")])
2110 [(set (match_operand:SF 0 "register_operand" "=r")
2111 (subreg:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2112 (match_operand:SI 2 "immediate_operand" "in")) 0))]
2114 "or %0,%1,%#lo16(%2)")
2117 [(set (match_operand:SF 0 "register_operand" "=r")
2118 (match_operand:SF 1 "immediate_operand" "F"))]
2119 "operands[1] != const0_rtx"
2120 "* return output_load_const_float (operands);"
2121 [(set_attr "type" "marith")]) ; length is 1 or 2.
2123 ;; String/block move insn. See m88k.c for details.
2125 (define_expand "movstrsi"
2126 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
2127 (mem:BLK (match_operand:BLK 1 "" "")))
2128 (use (match_operand:SI 2 "arith32_operand" ""))
2129 (use (match_operand:SI 3 "immediate_operand" ""))])]
2133 rtx dest_mem = operands[0];
2134 rtx src_mem = operands[1];
2135 operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
2136 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
2137 expand_block_move (dest_mem, src_mem, operands);
2142 [(set (match_operand:QI 0 "register_operand" "=r")
2143 (match_operand:BLK 1 "memory_operand" "m"))]
2146 [(set_attr "type" "load")])
2149 [(set (match_operand:HI 0 "register_operand" "=r")
2150 (match_operand:BLK 1 "memory_operand" "m"))]
2153 [(set_attr "type" "load")])
2156 [(set (match_operand:SI 0 "register_operand" "=r")
2157 (match_operand:BLK 1 "memory_operand" "m"))]
2160 [(set_attr "type" "load")])
2163 [(set (match_operand:DI 0 "register_operand" "=r")
2164 (match_operand:BLK 1 "memory_operand" "m"))]
2167 [(set_attr "type" "loadd")])
2170 [(set (match_operand:BLK 0 "memory_operand" "=m")
2171 (match_operand:QI 1 "register_operand" "r"))]
2174 [(set_attr "type" "store")])
2177 [(set (match_operand:BLK 0 "memory_operand" "=m")
2178 (match_operand:HI 1 "register_operand" "r"))]
2181 [(set_attr "type" "store")])
2184 [(set (match_operand:BLK 0 "memory_operand" "=m")
2185 (match_operand:SI 1 "register_operand" "r"))]
2188 [(set_attr "type" "store")])
2191 [(set (match_operand:BLK 0 "memory_operand" "=m")
2192 (match_operand:DI 1 "register_operand" "r"))]
2195 [(set_attr "type" "store")])
2197 ;; Call a non-looping block move library function (e.g. __movstrSI96x64).
2198 ;; operand 0 is the function name
2199 ;; operand 1 is the destination pointer
2200 ;; operand 2 is the source pointer
2201 ;; operand 3 is the offset for the source and destination pointers
2202 ;; operand 4 is the first value to be loaded
2203 ;; operand 5 is the register to hold the value (r4 or r5)
2205 (define_expand "call_block_move"
2206 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2207 (match_operand:SI 3 "immediate_operand" "")))
2208 (set (match_operand 5 "register_operand" "")
2209 (match_operand 4 "memory_operand" ""))
2210 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2215 (parallel [(set (reg:DI 2)
2216 (call (mem:SI (match_operand 0 "" ""))
2218 (clobber (reg:SI 1))])]
2222 ;; Call an SImode looping block move library function (e.g. __movstrSI64n68).
2223 ;; operands 0-5 as in the non-looping interface
2224 ;; operand 6 is the loop count
2226 (define_expand "call_movstrsi_loop"
2227 [(set (reg:SI 3) (minus:SI (match_operand:SI 2 "register_operand" "")
2228 (match_operand:SI 3 "immediate_operand" "")))
2229 (set (match_operand:SI 5 "register_operand" "")
2230 (match_operand 4 "memory_operand" ""))
2231 (set (reg:SI 2) (minus:SI (match_operand:SI 1 "register_operand" "")
2233 (set (reg:SI 6) (match_operand:SI 6 "immediate_operand" ""))
2238 (parallel [(set (reg:DI 2)
2239 (call (mem:SI (match_operand 0 "" ""))
2241 (clobber (reg:SI 1))])]
2245 ;;- zero extension instructions
2247 (define_expand "zero_extendhisi2"
2248 [(set (match_operand:SI 0 "register_operand" "")
2249 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2253 if (GET_CODE (operands[1]) == MEM
2254 && symbolic_address_p (XEXP (operands[1], 0)))
2256 = legitimize_address (flag_pic, operands[1], 0, 0);
2260 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2261 (zero_extend:SI (match_operand:HI 1 "move_operand" "!r,n,m")))]
2262 "GET_CODE (operands[1]) != CONST_INT"
2267 [(set_attr "type" "arith,arith,load")])
2269 (define_expand "zero_extendqihi2"
2270 [(set (match_operand:HI 0 "register_operand" "")
2271 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2275 if (GET_CODE (operands[1]) == MEM
2276 && symbolic_address_p (XEXP (operands[1], 0)))
2278 = legitimize_address (flag_pic, operands[1], 0, 0);
2282 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
2283 (zero_extend:HI (match_operand:QI 1 "move_operand" "r,n,m")))]
2284 "GET_CODE (operands[1]) != CONST_INT"
2289 [(set_attr "type" "arith,arith,load")])
2291 (define_expand "zero_extendqisi2"
2292 [(set (match_operand:SI 0 "register_operand" "")
2293 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2297 if (GET_CODE (operands[1]) == MEM
2298 && symbolic_address_p (XEXP (operands[1], 0)))
2301 = legitimize_address (flag_pic, operands[1], 0, 0);
2302 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
2303 gen_rtx (ZERO_EXTEND, SImode, operands[1])));
2309 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
2310 (zero_extend:SI (match_operand:QI 1 "move_operand" "r,n,m")))]
2311 "GET_CODE (operands[1]) != CONST_INT"
2316 [(set_attr "type" "arith,arith,load")])
2318 ;;- sign extension instructions
2320 (define_expand "extendsidi2"
2321 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=r") 1)
2322 (match_operand:SI 1 "general_operand" "g"))
2323 (set (subreg:SI (match_dup 0) 0)
2324 (ashiftrt:SI (subreg:SI (match_dup 0) 1)
2329 (define_expand "extendhisi2"
2330 [(set (match_operand:SI 0 "register_operand" "")
2331 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2335 if (GET_CODE (operands[1]) == MEM
2336 && symbolic_address_p (XEXP (operands[1], 0)))
2338 = legitimize_address (flag_pic, operands[1], 0, 0);
2342 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2343 (sign_extend:SI (match_operand:HI 1 "move_operand" "!r,P,N,m")))]
2344 "GET_CODE (operands[1]) != CONST_INT"
2350 [(set_attr "type" "bit,arith,arith,load")])
2352 (define_expand "extendqihi2"
2353 [(set (match_operand:HI 0 "register_operand" "")
2354 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
2358 if (GET_CODE (operands[1]) == MEM
2359 && symbolic_address_p (XEXP (operands[1], 0)))
2361 = legitimize_address (flag_pic, operands[1], 0, 0);
2365 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2366 (sign_extend:HI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2367 "GET_CODE (operands[1]) != CONST_INT"
2373 [(set_attr "type" "bit,arith,arith,load")])
2375 (define_expand "extendqisi2"
2376 [(set (match_operand:SI 0 "register_operand" "")
2377 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
2381 if (GET_CODE (operands[1]) == MEM
2382 && symbolic_address_p (XEXP (operands[1], 0)))
2384 = legitimize_address (flag_pic, operands[1], 0, 0);
2388 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2389 (sign_extend:SI (match_operand:QI 1 "move_operand" "!r,P,N,m")))]
2390 "GET_CODE (operands[1]) != CONST_INT"
2396 [(set_attr "type" "bit,arith,arith,load")])
2398 ;; Conversions between float and double.
2400 ;; The fadd instruction does not conform to IEEE 754 when used to
2401 ;; convert between float and double. In particular, the sign of -0 is
2402 ;; not preserved. Interestingly, fsub does conform.
2404 (define_expand "extendsfdf2"
2405 [(set (match_operand:DF 0 "register_operand" "=r")
2406 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2411 [(set (match_operand:DF 0 "register_operand" "=r")
2412 (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
2414 "fsub.dss %0,%1,%#r0"
2415 [(set_attr "type" "spadd")])
2418 [(set (match_operand:DF 0 "register_operand" "=r,x")
2419 (float_extend:DF (match_operand:SF 1 "register_operand" "r,x")))]
2422 [(set_attr "type" "spadd")])
2424 (define_expand "truncdfsf2"
2425 [(set (match_operand:SF 0 "register_operand" "=r")
2426 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2431 [(set (match_operand:SF 0 "register_operand" "=r")
2432 (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
2434 "fsub.sds %0,%1,%#r0"
2435 [(set_attr "type" "dpadd")])
2438 [(set (match_operand:SF 0 "register_operand" "=r,x")
2439 (float_truncate:SF (match_operand:DF 1 "register_operand" "r,x")))]
2442 [(set_attr "type" "dpadd")])
2444 ;; Conversions between floating point and integer
2446 (define_insn "floatsidf2"
2447 [(set (match_operand:DF 0 "register_operand" "=r,x")
2448 (float:DF (match_operand:SI 1 "register_operand" "r,r")))]
2451 [(set_attr "type" "spadd,dpadd")])
2453 (define_insn "floatsisf2"
2454 [(set (match_operand:SF 0 "register_operand" "=r,x")
2455 (float:SF (match_operand:SI 1 "register_operand" "r,r")))]
2458 [(set_attr "type" "spadd,spadd")])
2460 (define_insn "fix_truncdfsi2"
2461 [(set (match_operand:SI 0 "register_operand" "=r,r")
2462 (fix:SI (match_operand:DF 1 "register_operand" "r,x")))]
2465 [(set_attr "type" "dpadd,dpadd")])
2467 (define_insn "fix_truncsfsi2"
2468 [(set (match_operand:SI 0 "register_operand" "=r,r")
2469 (fix:SI (match_operand:SF 1 "register_operand" "r,x")))]
2472 [(set_attr "type" "spadd,dpadd")])
2475 ;;- arithmetic instructions
2476 ;;- add instructions
2478 (define_insn "addsi3"
2479 [(set (match_operand:SI 0 "register_operand" "=r,r")
2480 (plus:SI (match_operand:SI 1 "add_operand" "%r,r")
2481 (match_operand:SI 2 "add_operand" "rI,J")))]
2487 ;; patterns for mixed mode floating point.
2488 ;; Do not define patterns that utilize mixed mode arithmetic that result
2489 ;; in narrowing the precision, because it loses accuracy, since the standard
2490 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2492 (define_expand "adddf3"
2493 [(set (match_operand:DF 0 "register_operand" "=r,x")
2494 (plus:DF (match_operand:DF 1 "general_operand" "%r,x")
2495 (match_operand:DF 2 "general_operand" "r,x")))]
2499 operands[1] = legitimize_operand (operands[1], DFmode);
2500 operands[2] = legitimize_operand (operands[2], DFmode);
2504 [(set (match_operand:DF 0 "register_operand" "=r,x")
2505 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2506 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2509 [(set_attr "type" "spadd")])
2512 [(set (match_operand:DF 0 "register_operand" "=r,x")
2513 (plus:DF (match_operand:DF 1 "register_operand" "r,x")
2514 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2517 [(set_attr "type" "dpadd")])
2520 [(set (match_operand:DF 0 "register_operand" "=r,x")
2521 (plus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2522 (match_operand:DF 2 "register_operand" "r,x")))]
2525 [(set_attr "type" "dpadd")])
2528 [(set (match_operand:DF 0 "register_operand" "=r,x")
2529 (plus:DF (match_operand:DF 1 "register_operand" "%r,x")
2530 (match_operand:DF 2 "register_operand" "r,x")))]
2533 [(set_attr "type" "dpadd")])
2535 (define_insn "addsf3"
2536 [(set (match_operand:SF 0 "register_operand" "=r,x")
2537 (plus:SF (match_operand:SF 1 "register_operand" "%r,x")
2538 (match_operand:SF 2 "register_operand" "r,x")))]
2541 [(set_attr "type" "spadd")])
2544 [(set (match_operand:DI 0 "register_operand" "=r")
2545 (plus:DI (match_operand:DI 1 "register_operand" "r")
2547 (match_operand:SI 2 "register_operand" "r"))))
2548 (clobber (reg:CC 0))]
2550 "addu.co %d0,%d1,%2\;addu.ci %0,%1,%#r0"
2551 [(set_attr "type" "marith")])
2554 [(set (match_operand:DI 0 "register_operand" "=r")
2555 (plus:DI (zero_extend:DI
2556 (match_operand:SI 1 "register_operand" "r"))
2557 (match_operand:DI 2 "register_operand" "r")))
2558 (clobber (reg:CC 0))]
2560 "addu.co %d0,%1,%d2\;addu.ci %0,%#r0,%2"
2561 [(set_attr "type" "marith")])
2563 (define_insn "adddi3"
2564 [(set (match_operand:DI 0 "register_operand" "=r")
2565 (plus:DI (match_operand:DI 1 "register_operand" "%r")
2566 (match_operand:DI 2 "register_operand" "r")))
2567 (clobber (reg:CC 0))]
2569 "addu.co %d0,%d1,%d2\;addu.ci %0,%1,%2"
2570 [(set_attr "type" "marith")])
2572 ;; Add with carry insns.
2575 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2576 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2577 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2579 (unspec:CC [(match_dup 1) (match_dup 2)] 0))])]
2581 "addu.co %r0,%r1,%r2")
2584 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2585 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2588 "addu.co %#r0,%r0,%r1")
2591 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2592 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2593 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2596 "addu.ci %r0,%r1,%r2")
2598 ;;- subtract instructions
2600 (define_insn "subsi3"
2601 [(set (match_operand:SI 0 "register_operand" "=r")
2602 (minus:SI (match_operand:SI 1 "register_operand" "r")
2603 (match_operand:SI 2 "arith32_operand" "rI")))]
2607 ;; patterns for mixed mode floating point
2608 ;; Do not define patterns that utilize mixed mode arithmetic that result
2609 ;; in narrowing the precision, because it loses accuracy, since the standard
2610 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2612 (define_expand "subdf3"
2613 [(set (match_operand:DF 0 "register_operand" "=r,x")
2614 (minus:DF (match_operand:DF 1 "general_operand" "r,x")
2615 (match_operand:DF 2 "general_operand" "r,x")))]
2619 operands[1] = legitimize_operand (operands[1], DFmode);
2620 operands[2] = legitimize_operand (operands[2], DFmode);
2624 [(set (match_operand:DF 0 "register_operand" "=r,x")
2625 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2626 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2629 [(set_attr "type" "spadd")])
2632 [(set (match_operand:DF 0 "register_operand" "=r,x")
2633 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2634 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2637 [(set_attr "type" "dpadd")])
2640 [(set (match_operand:DF 0 "register_operand" "=r,x")
2641 (minus:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2642 (match_operand:DF 2 "register_operand" "r,x")))]
2645 [(set_attr "type" "dpadd")])
2648 [(set (match_operand:DF 0 "register_operand" "=r,x")
2649 (minus:DF (match_operand:DF 1 "register_operand" "r,x")
2650 (match_operand:DF 2 "register_operand" "r,x")))]
2653 [(set_attr "type" "dpadd")])
2655 (define_insn "subsf3"
2656 [(set (match_operand:SF 0 "register_operand" "=r,x")
2657 (minus:SF (match_operand:SF 1 "register_operand" "r,x")
2658 (match_operand:SF 2 "register_operand" "r,x")))]
2661 [(set_attr "type" "spadd")])
2664 [(set (match_operand:DI 0 "register_operand" "=r")
2665 (minus:DI (match_operand:DI 1 "register_operand" "r")
2667 (match_operand:SI 2 "register_operand" "r"))))
2668 (clobber (reg:CC 0))]
2670 "subu.co %d0,%d1,%2\;subu.ci %0,%1,%#r0"
2671 [(set_attr "type" "marith")])
2674 [(set (match_operand:DI 0 "register_operand" "=r")
2675 (minus:DI (zero_extend:DI
2676 (match_operand:SI 1 "register_operand" "r"))
2677 (match_operand:DI 2 "register_operand" "r")))
2678 (clobber (reg:CC 0))]
2680 "subu.co %d0,%1,%d2\;subu.ci %0,%#r0,%2"
2681 [(set_attr "type" "marith")])
2683 (define_insn "subdi3"
2684 [(set (match_operand:DI 0 "register_operand" "=r")
2685 (minus:DI (match_operand:DI 1 "register_operand" "r")
2686 (match_operand:DI 2 "register_operand" "r")))
2687 (clobber (reg:CC 0))]
2689 "subu.co %d0,%d1,%d2\;subu.ci %0,%1,%2"
2690 [(set_attr "type" "marith")])
2692 ;; Subtract with carry insns.
2695 [(parallel [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2696 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2697 (match_operand:SI 2 "reg_or_0_operand" "rO")))
2699 (unspec:CC [(match_dup 1) (match_dup 2)] 1))])]
2701 "subu.co %r0,%r1,%r2")
2704 [(set (reg:CC 0) (unspec:CC [(match_operand:SI 0 "reg_or_0_operand" "rO")
2705 (match_operand:SI 1 "reg_or_0_operand" "rO")]
2708 "subu.co %#r0,%r0,%r1")
2711 [(set (match_operand:SI 0 "reg_or_0_operand" "=r")
2712 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rO")
2713 (unspec:SI [(match_operand:SI 2 "reg_or_0_operand" "rO")
2716 "subu.ci %r0,%r1,%r2")
2718 ;;- multiply instructions
2720 ;; There is an unfounded silicon errata for E.1 requiring that an
2721 ;; immediate constant value in div/divu/mul instructions be less than
2722 ;; 0x800. This is no longer provided for.
2724 (define_insn "mulsi3"
2725 [(set (match_operand:SI 0 "register_operand" "=r")
2726 (mult:SI (match_operand:SI 1 "arith32_operand" "%r")
2727 (match_operand:SI 2 "arith32_operand" "rI")))]
2730 [(set_attr "type" "imul")])
2732 ;; Loses for acvs/P60504.c (mod case) on 88110
2733 ;; (define_insn "umulsidi3"
2734 ;; [(set (match_operand:DI 0 "register_operand" "=r")
2735 ;; (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
2736 ;; (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
2738 ;; "mulu.d %0,%1,%2"
2739 ;; [(set_attr "type" "imul")])
2741 ;; patterns for mixed mode floating point
2742 ;; Do not define patterns that utilize mixed mode arithmetic that result
2743 ;; in narrowing the precision, because it loses accuracy, since the standard
2744 ;; requires double rounding, whereas the 88000 instruction only rounds once.
2746 (define_expand "muldf3"
2747 [(set (match_operand:DF 0 "register_operand" "=r,x")
2748 (mult:DF (match_operand:DF 1 "general_operand" "%r,x")
2749 (match_operand:DF 2 "general_operand" "r,x")))]
2753 operands[1] = legitimize_operand (operands[1], DFmode);
2754 operands[2] = legitimize_operand (operands[2], DFmode);
2758 [(set (match_operand:DF 0 "register_operand" "=r,x")
2759 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2760 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2763 [(set_attr "type" "spmul")])
2766 [(set (match_operand:DF 0 "register_operand" "=r,x")
2767 (mult:DF (match_operand:DF 1 "register_operand" "r,x")
2768 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
2771 [(set_attr "type" "spmul")])
2774 [(set (match_operand:DF 0 "register_operand" "=r,x")
2775 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
2776 (match_operand:DF 2 "register_operand" "r,x")))]
2779 [(set_attr "type" "spmul")])
2782 [(set (match_operand:DF 0 "register_operand" "=r,x")
2783 (mult:DF (match_operand:DF 1 "register_operand" "%r,x")
2784 (match_operand:DF 2 "register_operand" "r,x")))]
2787 [(set_attr "type" "dpmul")])
2789 (define_insn "mulsf3"
2790 [(set (match_operand:SF 0 "register_operand" "=r,x")
2791 (mult:SF (match_operand:SF 1 "register_operand" "%r,x")
2792 (match_operand:SF 2 "register_operand" "r,x")))]
2795 [(set_attr "type" "spmul")])
2797 ;;- divide instructions
2799 ;; The 88k div and divu instructions don't reliably trap on
2800 ;; divide-by-zero. A trap to vector 503 asserts divide-by-zero. The
2801 ;; general scheme for doing divide is to do a 4-way split based on the
2802 ;; sign of the two operand and do the appropriate negates.
2804 ;; The conditional trap instruction is not used as this serializes the
2805 ;; processor. Instead a conditional branch and an unconditional trap
2806 ;; are used, but after the divu. Since the divu takes up to 38 cycles,
2807 ;; the conditional branch is essentially free.
2809 ;; Two target options control how divide is done. One options selects
2810 ;; whether to do the branch and negate scheme instead of using the div
2811 ;; instruction; the other option selects whether to explicitly check
2812 ;; for divide-by-zero or take your chances. If the div instruction is
2813 ;; used, the O/S must complete the operation if the operands are
2814 ;; negative. The O/S will signal an overflow condition if the most
2815 ;; negative number (-214783648) is divided by negative 1.
2817 ;; There is an unfounded silicon errata for E.1 requiring that an
2818 ;; immediate constant value in div/divu/mul instructions be less than
2819 ;; 0x800. This is no longer provided for.
2821 ;; Division by 0 trap
2822 (define_insn "trap_divide_by_zero"
2823 [(trap_if (const_int 1) 503)]
2826 [(set_attr "type" "weird")])
2828 ;; Conditional division by 0 trap.
2829 (define_expand "tcnd_divide_by_zero"
2831 (if_then_else (eq (match_operand:SI 0 "register_operand" "")
2834 (match_operand 1 "" "")))
2835 (trap_if (const_int 1) 503)]
2839 emit_insn (gen_cmpsi (operands[0], const0_rtx));
2840 emit_jump_insn (gen_bne (operands[1]));
2841 emit_insn (gen_trap_divide_by_zero ());
2845 (define_expand "divsi3"
2846 [(set (match_operand:SI 0 "register_operand" "")
2847 (div:SI (match_operand:SI 1 "arith32_operand" "")
2848 (match_operand:SI 2 "arith32_operand" "")))]
2852 rtx op0 = operands[0];
2853 rtx op1 = operands[1];
2854 rtx op2 = operands[2];
2857 /* @@ This needs to be reworked. Torbjorn Granlund has suggested making
2858 it a runtime (perhaps quite special). */
2860 if (GET_CODE (op1) == CONST_INT)
2861 op1 = force_reg (SImode, op1);
2863 else if (GET_CODE (op2) == CONST_INT
2864 && ! SMALL_INT (operands[2]))
2865 op2 = force_reg (SImode, op2);
2867 if (op2 == const0_rtx)
2869 emit_insn (gen_trap_divide_by_zero ());
2870 emit_insn (gen_dummy (op0));
2876 emit_move_insn (op0, gen_rtx (DIV, SImode, op1, op2));
2877 if (TARGET_CHECK_ZERO_DIV && GET_CODE (op2) != CONST_INT)
2879 rtx label = gen_label_rtx ();
2880 emit_insn (gen_tcnd_divide_by_zero (op2, label));
2882 emit_insn (gen_dummy (op0));
2887 join_label = gen_label_rtx ();
2888 if (GET_CODE (op1) == CONST_INT)
2891 rtx neg_op2 = gen_reg_rtx (SImode);
2892 rtx label1 = gen_label_rtx ();
2894 if (INTVAL (op1) < 0)
2897 op1 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op1));
2899 op1 = force_reg (SImode, op1);
2901 emit_insn (gen_negsi2 (neg_op2, op2));
2902 emit_insn (gen_cmpsi (op2, const0_rtx));
2903 emit_jump_insn (gen_bgt (label1));
2904 /* constant / 0-or-negative */
2905 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2907 emit_insn (gen_negsi2 (op0, op0));
2909 if (TARGET_CHECK_ZERO_DIV)
2910 emit_insn (gen_tcnd_divide_by_zero (op2, join_label));
2911 emit_jump_insn (gen_jump (join_label));
2914 emit_label (label1); /* constant / positive */
2915 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2917 emit_insn (gen_negsi2 (op0, op0));
2920 else if (GET_CODE (op2) == CONST_INT)
2923 rtx neg_op1 = gen_reg_rtx (SImode);
2924 rtx label1 = gen_label_rtx ();
2926 if (INTVAL (op2) < 0)
2929 op2 = gen_rtx (CONST_INT, VOIDmode, -INTVAL (op2));
2931 else if (! SMALL_INT (operands[2]))
2932 op2 = force_reg (SImode, op2);
2934 emit_insn (gen_negsi2 (neg_op1, op1));
2935 emit_insn (gen_cmpsi (op1, const0_rtx));
2936 emit_jump_insn (gen_bge (label1));
2937 /* 0-or-negative / constant */
2938 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
2940 emit_insn (gen_negsi2 (op0, op0));
2942 emit_jump_insn (gen_jump (join_label));
2945 emit_label (label1); /* positive / constant */
2946 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
2948 emit_insn (gen_negsi2 (op0, op0));
2953 rtx neg_op1 = gen_reg_rtx (SImode);
2954 rtx neg_op2 = gen_reg_rtx (SImode);
2955 rtx label1 = gen_label_rtx ();
2956 rtx label2 = gen_label_rtx ();
2957 rtx label3 = gen_label_rtx ();
2960 emit_insn (gen_negsi2 (neg_op2, op2));
2961 emit_insn (gen_cmpsi (op2, const0_rtx));
2962 emit_jump_insn (gen_bgt (label1));
2964 emit_insn (gen_negsi2 (neg_op1, op1));
2965 emit_insn (gen_cmpsi (op1, const0_rtx));
2966 emit_jump_insn (gen_bge (label2));
2967 /* negative / negative-or-0 */
2968 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, neg_op2));
2970 if (TARGET_CHECK_ZERO_DIV)
2972 label4 = gen_label_rtx ();
2973 emit_insn (gen_cmpsi (op2, const0_rtx));
2974 emit_jump_insn (gen_bne (join_label));
2975 emit_label (label4);
2976 emit_insn (gen_trap_divide_by_zero ());
2978 emit_jump_insn (gen_jump (join_label));
2981 emit_label (label2); /* pos.-or-0 / neg.-or-0 */
2982 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, neg_op2));
2984 if (TARGET_CHECK_ZERO_DIV)
2986 emit_insn (gen_cmpsi (op2, const0_rtx));
2987 emit_jump_insn (gen_beq (label4));
2990 emit_insn (gen_negsi2 (op0, op0));
2991 emit_jump_insn (gen_jump (join_label));
2994 emit_label (label1);
2995 emit_insn (gen_negsi2 (neg_op1, op1));
2996 emit_insn (gen_cmpsi (op1, const0_rtx));
2997 emit_jump_insn (gen_bge (label3));
2998 /* negative / positive */
2999 emit_move_insn (op0, gen_rtx (UDIV, SImode, neg_op1, op2));
3000 emit_insn (gen_negsi2 (op0, op0));
3001 emit_jump_insn (gen_jump (join_label));
3004 emit_label (label3); /* positive-or-0 / positive */
3005 emit_move_insn (op0, gen_rtx (UDIV, SImode, op1, op2));
3008 emit_label (join_label);
3010 emit_insn (gen_dummy (op0));
3015 [(set (match_operand:SI 0 "register_operand" "=r")
3016 (div:SI (match_operand:SI 1 "register_operand" "r")
3017 (match_operand:SI 2 "arith_operand" "rI")))]
3020 [(set_attr "type" "idiv")])
3022 (define_expand "udivsi3"
3023 [(set (match_operand:SI 0 "register_operand" "")
3024 (udiv:SI (match_operand:SI 1 "register_operand" "")
3025 (match_operand:SI 2 "arith32_operand" "")))]
3029 rtx op2 = operands[2];
3031 if (op2 == const0_rtx)
3033 emit_insn (gen_trap_divide_by_zero ());
3034 emit_insn (gen_dummy (operands[0]));
3037 else if (GET_CODE (op2) != CONST_INT && TARGET_CHECK_ZERO_DIV)
3039 rtx label = gen_label_rtx ();
3040 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3041 gen_rtx (UDIV, SImode, operands[1], op2)));
3042 emit_insn (gen_tcnd_divide_by_zero (op2, label));
3044 emit_insn (gen_dummy (operands[0]));
3050 [(set (match_operand:SI 0 "register_operand" "=r")
3051 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3052 (match_operand:SI 2 "arith32_operand" "rI")))]
3053 "operands[2] != const0_rtx"
3055 [(set_attr "type" "idiv")])
3058 [(set (match_operand:SI 0 "register_operand" "=r")
3059 (udiv:SI (match_operand:SI 1 "register_operand" "r")
3063 [(set_attr "type" "weird")])
3065 ;; patterns for mixed mode floating point.
3066 ;; Do not define patterns that utilize mixed mode arithmetic that result
3067 ;; in narrowing the precision, because it loses accuracy, since the standard
3068 ;; requires double rounding, whereas the 88000 instruction only rounds once.
3070 (define_expand "divdf3"
3071 [(set (match_operand:DF 0 "register_operand" "=r,x")
3072 (div:DF (match_operand:DF 1 "general_operand" "r,x")
3073 (match_operand:DF 2 "general_operand" "r,x")))]
3077 operands[1] = legitimize_operand (operands[1], DFmode);
3078 if (real_power_of_2_operand (operands[2]))
3080 union real_extract u;
3081 bcopy (&CONST_DOUBLE_LOW (operands[2]), &u, sizeof u);
3082 emit_insn (gen_muldf3 (operands[0], operands[1],
3083 CONST_DOUBLE_FROM_REAL_VALUE (1.0/u.d, DFmode)));
3086 else if (! register_operand (operands[2], DFmode))
3087 operands[2] = force_reg (DFmode, operands[2]);
3091 [(set (match_operand:DF 0 "register_operand" "=r,x")
3092 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3093 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3096 [(set_attr "type" "dpdiv")])
3099 [(set (match_operand:DF 0 "register_operand" "=r,x")
3100 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3101 (float_extend:DF (match_operand:SF 2 "register_operand" "r,x"))))]
3104 [(set_attr "type" "dpdiv")])
3107 [(set (match_operand:DF 0 "register_operand" "=r,x")
3108 (div:DF (float_extend:DF (match_operand:SF 1 "register_operand" "r,x"))
3109 (match_operand:DF 2 "register_operand" "r,x")))]
3112 [(set_attr "type" "dpdiv")])
3114 (define_insn "divsf3"
3115 [(set (match_operand:SF 0 "register_operand" "=r,x")
3116 (div:SF (match_operand:SF 1 "register_operand" "r,x")
3117 (match_operand:SF 2 "register_operand" "r,x")))]
3120 [(set_attr "type" "spdiv")])
3123 [(set (match_operand:DF 0 "register_operand" "=r,x")
3124 (div:DF (match_operand:DF 1 "register_operand" "r,x")
3125 (match_operand:DF 2 "register_operand" "r,x")))]
3128 [(set_attr "type" "dpdiv")])
3130 ;; - remainder instructions, don't define, since the hardware doesn't have any
3131 ;; direct support, and GNU can synthesis them out of div/mul just fine.
3133 ;;- load effective address, must come after add, so that we favor using
3134 ;; addu reg,reg,reg instead of: lda reg,reg,reg (addu doesn't require
3135 ;; the data unit), and also future 88k chips might not support unscaled
3136 ;; lda instructions.
3139 [(set (match_operand:SI 0 "register_operand" "=r")
3140 (match_operand:SI 1 "address_operand" "p"))]
3141 "m88k_gp_threshold > 0 && symbolic_address_p (operands[1])"
3145 [(set (match_operand:SI 0 "register_operand" "=r")
3146 (match_operand:HI 1 "address_operand" "p"))]
3149 [(set_attr "type" "loada")])
3152 [(set (match_operand:SI 0 "register_operand" "=r")
3153 (match_operand:SI 1 "address_operand" "p"))]
3156 [(set_attr "type" "loada")])
3159 [(set (match_operand:SI 0 "register_operand" "=r")
3160 (match_operand:DI 1 "address_operand" "p"))]
3163 [(set_attr "type" "loada")])
3166 [(set (match_operand:SI 0 "register_operand" "=r")
3167 (match_operand:SF 1 "address_operand" "p"))]
3170 [(set_attr "type" "loada")])
3173 [(set (match_operand:SI 0 "register_operand" "=r")
3174 (match_operand:DF 1 "address_operand" "p"))]
3177 [(set_attr "type" "loada")])
3179 ;;- and instructions (with complement also)
3181 [(set (match_operand:SI 0 "register_operand" "=r")
3182 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3183 (match_operand:SI 2 "register_operand" "r")))]
3187 ;; If the operation is being performed on a 32-bit constant such that
3188 ;; it cannot be done in one insn, do it in two. We may lose a bit on
3189 ;; CSE in pathological cases, but it seems better doing it this way.
3191 (define_expand "andsi3"
3192 [(set (match_operand:SI 0 "register_operand" "")
3193 (and:SI (match_operand:SI 1 "arith32_operand" "")
3194 (match_operand:SI 2 "arith32_operand" "")))]
3198 if (GET_CODE (operands[2]) == CONST_INT)
3200 int value = INTVAL (operands[2]);
3202 if (! (SMALL_INTVAL (value)
3203 || (value & 0xffff0000) == 0xffff0000
3204 || (value & 0xffff) == 0xffff
3205 || (value & 0xffff) == 0
3206 || integer_ok_for_set (~value)))
3208 emit_insn (gen_andsi3 (operands[0], operands[1],
3209 gen_rtx (CONST_INT, VOIDmode,
3211 operands[1] = operands[0];
3212 operands[2] = gen_rtx (CONST_INT, VOIDmode, value | 0xffff0000);
3218 [(set (match_operand:SI 0 "register_operand" "=r,r")
3219 (and:SI (match_operand:SI 1 "arith32_operand" "%r,r")
3220 (match_operand:SI 2 "arith32_operand" "rIJL,rn")))]
3222 "* return output_and (operands);"
3223 [(set_attr "type" "arith,marith")])
3226 [(set (match_operand:DI 0 "register_operand" "=r")
3227 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3228 (match_operand:DI 2 "register_operand" "r")))]
3230 "and.c %d0,%d2,%d1\;and.c %0,%2,%1"
3231 [(set_attr "type" "marith")])
3233 (define_insn "anddi3"
3234 [(set (match_operand:DI 0 "register_operand" "=r")
3235 (and:DI (match_operand:DI 1 "arith64_operand" "%r")
3236 (match_operand:DI 2 "arith64_operand" "rn")))]
3242 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3243 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3244 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3246 output_asm_insn (output_and (xoperands), xoperands);
3248 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3249 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3250 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3252 return output_and (operands);
3254 [(set_attr "type" "marith")
3255 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3257 ;;- Bit set (inclusive or) instructions (with complement also)
3259 [(set (match_operand:SI 0 "register_operand" "=r")
3260 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3261 (match_operand:SI 2 "register_operand" "r")))]
3265 (define_expand "iorsi3"
3266 [(set (match_operand:SI 0 "register_operand" "")
3267 (ior:SI (match_operand:SI 1 "arith32_operand" "")
3268 (match_operand:SI 2 "arith32_operand" "")))]
3272 if (GET_CODE (operands[2]) == CONST_INT)
3274 int value = INTVAL (operands[2]);
3276 if (! (SMALL_INTVAL (value)
3277 || (value & 0xffff) == 0
3278 || integer_ok_for_set (value)))
3280 emit_insn (gen_iorsi3 (operands[0], operands[1],
3281 gen_rtx (CONST_INT, VOIDmode,
3282 value & 0xffff0000)));
3283 operands[1] = operands[0];
3284 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3290 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3291 (ior:SI (match_operand:SI 1 "arith32_operand" "%r,r,r,r")
3292 (match_operand:SI 2 "arith32_operand" "rI,L,M,n")))]
3298 or.u %0,%1,%X2\;or %0,%0,%x2"
3299 [(set_attr "type" "arith,arith,bit,marith")])
3302 [(set (match_operand:DI 0 "register_operand" "=r")
3303 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3304 (match_operand:DI 2 "register_operand" "r")))]
3306 "or.c %d0,%d2,%d1\;or.c %0,%2,%1"
3307 [(set_attr "type" "marith")])
3309 (define_insn "iordi3"
3310 [(set (match_operand:DI 0 "register_operand" "=r")
3311 (ior:DI (match_operand:DI 1 "arith64_operand" "%r")
3312 (match_operand:DI 2 "arith64_operand" "rn")))]
3318 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3319 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3320 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3322 output_asm_insn (output_ior (xoperands), xoperands);
3324 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3325 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3326 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3328 return output_ior (operands);
3330 [(set_attr "type" "marith")
3331 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3333 ;;- xor instructions (with complement also)
3335 [(set (match_operand:SI 0 "register_operand" "=r")
3336 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%r")
3337 (match_operand:SI 2 "register_operand" "r"))))]
3341 (define_expand "xorsi3"
3342 [(set (match_operand:SI 0 "register_operand" "")
3343 (xor:SI (match_operand:SI 1 "arith32_operand" "")
3344 (match_operand:SI 2 "arith32_operand" "")))]
3348 if (GET_CODE (operands[2]) == CONST_INT)
3350 int value = INTVAL (operands[2]);
3352 if (! (SMALL_INTVAL (value)
3353 || (value & 0xffff) == 0))
3355 emit_insn (gen_xorsi3 (operands[0], operands[1],
3356 gen_rtx (CONST_INT, VOIDmode,
3357 value & 0xffff0000)));
3358 operands[1] = operands[0];
3359 operands[2] = gen_rtx (CONST_INT, VOIDmode, value & 0xffff);
3365 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3366 (xor:SI (match_operand:SI 1 "arith32_operand" "%r,r,r")
3367 (match_operand:SI 2 "arith32_operand" "rI,L,n")))]
3372 xor.u %0,%1,%X2\;xor %0,%0,%x2"
3373 [(set_attr "type" "arith,arith,marith")])
3376 [(set (match_operand:DI 0 "register_operand" "=r")
3377 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3378 (match_operand:DI 2 "register_operand" "r"))))]
3380 "xor.c %d0,%d1,%d2\;xor.c %0,%1,%2"
3381 [(set_attr "type" "marith")])
3383 (define_insn "xordi3"
3384 [(set (match_operand:DI 0 "register_operand" "=r")
3385 (xor:DI (match_operand:DI 1 "arith64_operand" "%r")
3386 (match_operand:DI 2 "arith64_operand" "rn")))]
3392 xoperands[0] = operand_subword (operands[0], 1, 0, DImode);
3393 xoperands[1] = operand_subword (operands[1], 1, 0, DImode);
3394 xoperands[2] = operand_subword (operands[2], 1, 0, DImode);
3396 output_asm_insn (output_xor (xoperands), xoperands);
3398 operands[0] = operand_subword (operands[0], 0, 0, DImode);
3399 operands[1] = operand_subword (operands[1], 0, 0, DImode);
3400 operands[2] = operand_subword (operands[2], 0, 0, DImode);
3402 return output_xor (operands);
3404 [(set_attr "type" "marith")
3405 (set_attr "length" "4")]) ; length is 2, 3, or 4.
3407 ;;- ones complement instructions
3408 (define_insn "one_cmplsi2"
3409 [(set (match_operand:SI 0 "register_operand" "=r")
3410 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3414 (define_insn "one_cmpldi2"
3415 [(set (match_operand:DI 0 "register_operand" "=r")
3416 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3418 "xor.c %d0,%d1,%#r0\;xor.c %0,%1,%#r0"
3419 [(set_attr "type" "marith")])
3421 ;; Optimized special cases of shifting.
3422 ;; Must precede the general case.
3424 ;; @@ What about HImode shifted by 8?
3427 [(set (match_operand:SI 0 "register_operand" "=r")
3428 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3430 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3432 [(set_attr "type" "load")])
3435 [(set (match_operand:SI 0 "register_operand" "=r")
3436 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3438 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3440 [(set_attr "type" "load")])
3443 [(set (match_operand:SI 0 "register_operand" "=r")
3444 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3446 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3448 [(set_attr "type" "load")])
3451 [(set (match_operand:SI 0 "register_operand" "=r")
3452 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
3454 "! SCALED_ADDRESS_P (XEXP (operands[1], 0))"
3456 [(set_attr "type" "load")])
3458 ;;- arithmetic shift instructions.
3460 ;; @@ Do the optimized patterns with -1 get used? Perhaps operand 1 should
3461 ;; be arith32_operand?
3463 ;; Use tbnd to support TARGET_TRAP_LARGE_SHIFT.
3465 [(trap_if (gtu (match_operand:SI 0 "register_operand" "r")
3466 (match_operand:SI 1 "arith_operand" "rI"))
3470 [(set_attr "type" "weird")])
3472 ;; Just in case the optimizer decides to fold away the test.
3474 [(trap_if (const_int 1) 7)]
3477 [(set_attr "type" "weird")])
3479 (define_expand "ashlsi3"
3480 [(set (match_operand:SI 0 "register_operand" "")
3481 (ashift:SI (match_operand:SI 1 "register_operand" "")
3482 (match_operand:SI 2 "arith32_operand" "")))]
3486 if (GET_CODE (operands[2]) == CONST_INT)
3488 if ((unsigned) INTVAL (operands[2]) > 31)
3490 if (TARGET_TRAP_LARGE_SHIFT)
3491 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3492 gen_rtx (CONST_INT, VOIDmode, 31)));
3494 emit_move_insn (operands[0], const0_rtx);
3499 else if (TARGET_TRAP_LARGE_SHIFT)
3500 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3502 else if (TARGET_HANDLE_LARGE_SHIFT)
3504 rtx reg = gen_reg_rtx (SImode);
3505 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3506 emit_insn (gen_sleu (reg));
3507 emit_insn (gen_andsi3 (reg, operands[1], reg));
3513 [(set (match_operand:SI 0 "register_operand" "=r,r")
3514 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
3515 (match_operand:SI 2 "arith5_operand" "r,K")))]
3520 [(set_attr "type" "bit")])
3522 (define_expand "ashrsi3"
3523 [(set (match_operand:SI 0 "register_operand" "")
3524 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3525 (match_operand:SI 2 "arith32_operand" "")))]
3529 if (GET_CODE (operands[2]) == CONST_INT)
3531 if ((unsigned) INTVAL (operands[2]) > 31)
3533 if (TARGET_TRAP_LARGE_SHIFT)
3535 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3536 gen_rtx (CONST_INT, VOIDmode, 31)));
3540 operands[2] = gen_rtx (CONST_INT, VOIDmode, 31);
3544 else if (TARGET_TRAP_LARGE_SHIFT)
3545 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3547 else if (TARGET_HANDLE_LARGE_SHIFT)
3549 rtx reg = gen_reg_rtx (SImode);
3550 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3551 emit_insn (gen_sgtu (reg));
3552 emit_insn (gen_iorsi3 (reg, operands[2], reg));
3558 [(set (match_operand:SI 0 "register_operand" "=r,r")
3559 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3560 (match_operand:SI 2 "arith5_operand" "r,K")))]
3565 [(set_attr "type" "bit")])
3567 ;;- logical shift instructions. Logical shift left becomes arithmetic
3570 (define_expand "lshrsi3"
3571 [(set (match_operand:SI 0 "register_operand" "")
3572 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3573 (match_operand:SI 2 "arith32_operand" "")))]
3577 if (GET_CODE (operands[2]) == CONST_INT)
3579 if ((unsigned) INTVAL (operands[2]) > 31)
3581 if (TARGET_TRAP_LARGE_SHIFT)
3582 emit_insn (gen_tbnd (force_reg (SImode, operands[2]),
3583 gen_rtx (CONST_INT, VOIDmode, 31)));
3585 emit_move_insn (operands[0], const0_rtx);
3590 else if (TARGET_TRAP_LARGE_SHIFT)
3591 emit_insn (gen_tbnd (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3593 else if (TARGET_HANDLE_LARGE_SHIFT)
3595 rtx reg = gen_reg_rtx (SImode);
3596 emit_insn (gen_cmpsi (operands[2], gen_rtx (CONST_INT, VOIDmode, 31)));
3597 emit_insn (gen_sleu (reg));
3598 emit_insn (gen_andsi3 (reg, operands[1], reg));
3604 [(set (match_operand:SI 0 "register_operand" "=r,r")
3605 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
3606 (match_operand:SI 2 "arith5_operand" "r,K")))]
3611 [(set_attr "type" "bit")])
3613 ;;- rotate instructions
3615 (define_expand "rotlsi3"
3616 [(set (match_operand:SI 0 "register_operand" "")
3617 (rotatert:SI (match_operand:SI 1 "register_operand" "")
3618 (match_operand:SI 2 "arith32_operand" "")))]
3622 if (GET_CODE (operands[2]) == CONST_INT
3623 && (unsigned) INTVAL (operands[2]) >= 32)
3624 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3625 (32 - INTVAL (operands[2])) % 32);
3628 rtx op = gen_reg_rtx (SImode);
3629 emit_insn (gen_negsi2 (op, operands[2]));
3634 (define_insn "rotrsi3"
3635 [(set (match_operand:SI 0 "register_operand" "=r")
3636 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
3637 (match_operand:SI 2 "arith_operand" "rI")))]
3640 [(set_attr "type" "bit")])
3644 ;; The ff1 instruction searches from the most significant bit while ffs
3645 ;; searches from the least significant bit. The bit index and treatment of
3646 ;; zero also differ. This amazing sequence was discovered using the GNU
3649 (define_insn "ffssi2"
3650 [(set (match_operand:SI 0 "register_operand" "=r,&r")
3651 (ffs:SI (match_operand:SI 1 "register_operand" "0,r")))
3652 (clobber (reg:CC 0))
3653 (clobber (match_scratch:SI 2 "=r,X"))]
3656 subu.co %2,%#r0,%1\;and %2,%2,%1\;addu.ci %2,%2,%2\;ff1 %0,%2
3657 subu.co %0,%#r0,%1\;and %0,%0,%1\;addu.ci %0,%0,%0\;ff1 %0,%0"
3658 [(set_attr "type" "marith")
3659 (set_attr "length" "4")])
3661 ;; Bit field instructions.
3664 [(set (match_operand:SI 0 "register_operand" "=r")
3665 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3672 [(set (match_operand:SI 0 "register_operand" "=r")
3673 (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
3674 (match_operand:SI 2 "int5_operand" "")
3675 (match_operand:SI 3 "int5_operand" "")))]
3679 operands[4] = gen_rtx (CONST_INT, SImode,
3680 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3681 return \"ext %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3683 [(set_attr "type" "bit")])
3686 [(set (match_operand:SI 0 "register_operand" "=r")
3687 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3693 (define_insn "extzv"
3694 [(set (match_operand:SI 0 "register_operand" "=r")
3695 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
3696 (match_operand:SI 2 "int5_operand" "")
3697 (match_operand:SI 3 "int5_operand" "")))]
3701 operands[4] = gen_rtx (CONST_INT, SImode,
3702 (32 - INTVAL (operands[2])) - INTVAL (operands[3]));
3703 return \"extu %0,%1,%2<%4>\"; /* <(32-%2-%3)> */
3705 [(set_attr "type" "bit")])
3708 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3709 (match_operand:SI 1 "int5_operand" "")
3710 (match_operand:SI 2 "int5_operand" ""))
3715 operands[3] = gen_rtx (CONST_INT, SImode,
3716 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3717 return \"clr %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3719 [(set_attr "type" "bit")])
3722 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3723 (match_operand:SI 1 "int5_operand" "")
3724 (match_operand:SI 2 "int5_operand" ""))
3729 operands[3] = gen_rtx (CONST_INT, SImode,
3730 (32 - INTVAL (operands[1])) - INTVAL (operands[2]));
3731 return \"set %0,%0,%1<%3>\"; /* <(32-%1-%2)> */
3733 [(set_attr "type" "bit")])
3736 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
3737 (match_operand:SI 1 "int5_operand" "")
3738 (match_operand:SI 2 "int5_operand" ""))
3739 (match_operand:SI 3 "int32_operand" "n"))]
3743 int value = INTVAL (operands[3]);
3745 if (INTVAL (operands[1]) < 32)
3746 value &= (1 << INTVAL (operands[1])) - 1;
3748 operands[2] = gen_rtx (CONST_INT, VOIDmode,
3749 32 - (INTVAL(operands[1]) + INTVAL(operands[2])));
3751 value <<= INTVAL (operands[2]);
3752 operands[3] = gen_rtx (CONST_INT, VOIDmode, value);
3754 if (SMALL_INTVAL (value))
3755 return \"clr %0,%0,%1<%2>\;or %0,%0,%3\";
3756 else if ((value & 0x0000ffff) == 0)
3757 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\";
3759 return \"clr %0,%0,%1<%2>\;or.u %0,%0,%X3\;or %0,%0,%x3\";
3761 [(set_attr "type" "marith")
3762 (set_attr "length" "3")]) ; may be 2 or 3.
3765 (define_insn "negsi2"
3766 [(set (match_operand:SI 0 "register_operand" "=r")
3767 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
3772 [(set (match_operand:SF 0 "register_operand" "=r,x")
3773 (float_truncate:SF (neg:DF (match_operand:DF 1 "register_operand" "r,x"))))]
3777 fsub.ssd %0,%#x0,%1"
3778 [(set_attr "type" "dpadd")])
3780 (define_insn "negdf2"
3781 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3782 (neg:DF (match_operand:DF 1 "register_operand" "r,0")))]
3785 xor.u %0,%1,0x8000\;or %d0,%#r0,%d1
3787 [(set_attr "type" "marith,arith")])
3789 (define_insn "negsf2"
3790 [(set (match_operand:SF 0 "register_operand" "=r")
3791 (neg:SF (match_operand:SF 1 "register_operand" "r")))]
3793 "xor.u %0,%1,0x8000")
3795 ;; absolute value insns for floating-point (integer abs can be done using the
3796 ;; machine-independent sequence).
3798 (define_insn "absdf2"
3799 [(set (match_operand:DF 0 "register_operand" "=&r,r")
3800 (abs:DF (match_operand:DF 1 "register_operand" "r,0")))]
3803 and.u %0,%1,0x7fff\;or %d0,%#r0,%d1
3805 [(set_attr "type" "marith,arith")])
3807 (define_insn "abssf2"
3808 [(set (match_operand:SF 0 "register_operand" "=r")
3809 (abs:SF (match_operand:SF 1 "register_operand" "r")))]
3811 "and.u %0,%1,0x7fff")
3813 ;; Subroutines of "casesi".
3815 ;; Operand 0 is index
3816 ;; operand 1 is the minimum bound
3817 ;; operand 2 is the maximum bound - minimum bound + 1
3818 ;; operand 3 is CODE_LABEL for the table;
3819 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3821 (define_expand "casesi"
3822 ;; We don't use these for generating the RTL, but we must describe
3823 ;; the operands here.
3824 [(match_operand:SI 0 "general_operand" "")
3825 (match_operand:SI 1 "immediate_operand" "")
3826 (match_operand:SI 2 "immediate_operand" "")
3827 (match_operand 3 "" "")
3828 (match_operand 4 "" "")]
3832 register rtx index_diff = gen_reg_rtx (SImode);
3833 register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
3834 register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
3837 if (! CASE_VECTOR_INSNS)
3838 /* These instructions are likely to be scheduled and made loop invariant.
3839 This decreases the cost of the dispatch at the expense of the default
3841 base = force_reg (SImode, memory_address_noforce (SImode, label));
3843 /* Compute the index difference and handle the default case. */
3844 emit_insn (gen_addsi3 (index_diff,
3845 force_reg (SImode, operands[0]),
3846 ADD_INT (low) ? low : force_reg (SImode, low)));
3847 emit_insn (gen_cmpsi (index_diff, operands[2]));
3848 /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
3849 entry to the table. However, that doesn't seem to win on the m88110. */
3850 emit_jump_insn (gen_bgtu (operands[4]));
3852 if (CASE_VECTOR_INSNS)
3853 /* Call the jump that will branch to the appropriate case. */
3854 emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
3856 /* Load the table entry and jump to it. */
3857 emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff, operands[3]));
3859 /* Claim that flow drops into the table so it will be adjacent by not
3860 emitting a barrier. */
3864 (define_expand "casesi_jump"
3865 [(set (match_operand:SI 0 "" "")
3866 (mem:SI (plus:SI (match_operand:SI 1 "" "")
3867 (mult:SI (match_operand:SI 2 "" "")
3869 (parallel [(set (pc) (match_dup 0))
3870 (use (label_ref (match_operand 3 "" "")))])]
3875 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
3876 (use (label_ref (match_operand 1 "" "")))]
3879 [(set_attr "type" "jump")])
3881 ;; The bsr.n instruction is directed to the END of the table. See
3882 ;; ASM_OUTPUT_CASE_END.
3884 (define_insn "casesi_enter"
3885 [(set (pc) (match_operand 0 "" ""))
3886 (use (match_operand:SI 1 "register_operand" "r"))
3887 ;; The USE here is so that at least one jump-insn will refer to the label,
3888 ;; to keep it alive in jump_optimize.
3889 (use (label_ref (match_operand 2 "" "")))
3890 (clobber (reg:SI 1))]
3894 if (flag_delayed_branch)
3895 return \"bsr.n %0e\;lda %#r1,%#r1[%1]\";
3896 m88k_case_index = REGNO (operands[1]);
3899 [(set_attr "type" "weird")
3900 (set_attr "length" "3")]) ; Including the "jmp r1".
3902 ;;- jump to subroutine
3903 (define_expand "call"
3904 [(parallel [(call (match_operand:SI 0 "" "")
3905 (match_operand 1 "" ""))
3906 (clobber (reg:SI 1))])]
3910 if (GET_CODE (operands[0]) == MEM
3911 && ! call_address_operand (XEXP (operands[0], 0), SImode))
3912 operands[0] = gen_rtx (MEM, GET_MODE (operands[0]),
3913 force_reg (Pmode, XEXP (operands[0], 0)));
3917 [(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
3918 (match_operand 1 "" ""))
3919 (clobber (reg:SI 1))])]
3921 "* return output_call (operands, operands[0]);"
3922 [(set_attr "type" "call")])
3924 (define_expand "call_value"
3925 [(parallel [(set (match_operand 0 "register_operand" "")
3926 (call (match_operand:SI 1 "" "")
3927 (match_operand 2 "" "")))
3928 (clobber (reg:SI 1))])]
3932 if (GET_CODE (operands[1]) == MEM
3933 && ! call_address_operand (XEXP (operands[1], 0), SImode))
3934 operands[1] = gen_rtx (MEM, GET_MODE (operands[1]),
3935 force_reg (Pmode, XEXP (operands[1], 0)));
3939 [(parallel [(set (match_operand 0 "register_operand" "=r")
3941 (match_operand:SI 1 "call_address_operand" "rQ"))
3942 (match_operand 2 "" "")))
3943 (clobber (reg:SI 1))])]
3945 "* return output_call (operands, operands[1]);"
3946 [(set_attr "type" "call")])
3948 ;; Nop instruction and others
3954 [(set_attr "type" "bit")])
3956 (define_insn "return"
3960 [(set_attr "type" "jump")])
3962 (define_expand "prologue"
3965 "m88k_expand_prologue (); DONE;")
3967 (define_expand "epilogue"
3969 "! null_prologue ()"
3970 "m88k_expand_epilogue ();")
3972 (define_insn "blockage"
3973 [(unspec_volatile [(const_int 0)] 0)]
3976 [(set_attr "length" "0")])
3978 (define_insn "indirect_jump"
3979 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
3982 [(set_attr "type" "jump")])
3986 (label_ref (match_operand 0 "" "")))]
3989 [(set_attr "type" "jump")])
3991 ;; This insn is used for some loop tests, typically loops reversed when
3992 ;; strength reduction is used. It is actually created when the instruction
3993 ;; combination phase combines the special loop test. Since this insn
3994 ;; is both a jump insn and has an output, it must deal with it's own
3995 ;; reloads, hence the `m' constraints. The `!' constraints direct reload
3996 ;; to not choose the register alternatives in the event a reload is needed.
3998 (define_insn "decrement_and_branch_until_zero"
4001 (match_operator 0 "relop_no_unsigned"
4002 [(match_operand:SI 1 "register_operand" "+!r,!r,m,m")
4004 (label_ref (match_operand 2 "" ""))
4007 (plus:SI (match_dup 1)
4008 (match_operand:SI 3 "add_operand" "rI,J,rI,J")))
4009 (clobber (match_scratch:SI 4 "=X,X,&r,&r"))
4010 (clobber (match_scratch:SI 5 "=X,X,&r,&r"))]
4011 "find_reg_note (insn, REG_NONNEG, 0)"
4013 bcnd.n %B0,%1,%2\;addu %1,%1,%3
4014 bcnd.n %B0,%1,%2\;subu %1,%1,%n3
4015 ld %4,%1\;addu %5,%4,%3\;bcnd.n %B0,%4,%2\;st %5,%1
4016 ld %4,%1\;subu %5,%4,%n3\;bcnd.n %B0,%4,%2\;st %5,%1"
4017 [(set_attr "type" "weird")
4018 (set_attr "length" "2,2,4,4")])
4020 ;; Special insn to serve as the last insn of a define_expand. This insn
4021 ;; will generate no code.
4023 (define_expand "dummy"
4024 [(set (match_operand 0 "" "") (match_dup 0))]