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