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