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