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